I'm trying to upload data to a file using the Google Drive v3 API by making a XMLHttpRequest.
I get the id of a file using the File Picker API which returns "0BzAI5S8IJebrUnQtYWFSVzhPdVk", so that the upload URL should be "https://www.googleapis.com/upload/drive/v3/files/0BzAI5S8IJebrUnQtYWFSVzhPdVk?uploadType=resumable".
After I make the PUT request, it returns a 404 status code with "Not Found" as the responseText.
I've tried it before and it would return with status 200 and I was able to get the Location header from the response, but now I can't get a 200 status code from any file.
Here's my code:
// Log the user in using attachClickHandler (https://developers.google.com/identity/sign-in/web/reference#googleauthattachclickhandlercontainer-options--onsuccess-onfailure)
var id = "0BzAI5S8IJebrOFVMTU5Od183Q2M";
var access_token = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token;
var xhr = new XMLHttpRequest();
xhr.open('PUT', 'https://www.googleapis.com/upload/drive/v3/files/' + id + '?uploadType=resumable');
xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
xhr.onreadystatechange = function() {
if (this.readyState == 4) console.log(this.status);
};
xhr.send();
No matter which file I choose, it always outputs 404 as the status code. I follow what it says at https://developers.google.com/drive/v3/web/resumable-upload, but it mentions nothing of why you would receive a 404 response. Any help?
Turns out I was trying to do the wrong thing. I wanted to update a file, not upload one. Instead of using "PUT", I should've been using "PATCH" as explained here. This returned a 200 response with the Location header to make the actual change.
Related
I am trying to use a vanilla JS AJAX request to pull back a JSON string from a locally stored JSON file (specifically trying not to use JQuery) - the below code is based on this answer - but I keep getting an error in the Chrome console (see below). Any ideas where I'm going wrong? I have tried changing the positioning of the xhr.open & .send requests, but still get error messages. I suspect the issue lies with the .send() request?
//Vanilla JS AJAX request to get species from JSON file & populate Select box
function getJSON(path,callback) {
var xhr = new XMLHttpRequest(); //Instantiate new request
xhr.open('GET', path ,true); //prepare asynch GET request
xhr.send(); //send request
xhr.onreadystatechange = function(){ //everytime ready state changes (0-4), check it
if (xhr.readyState === 4) { //if request finished & response ready (4)
if (xhr.status === 0 || xhr.status === 200) { //then if status OK (local file || server)
var data = JSON.parse(xhr.responseText); //parse the returned JSON string
if (callback) {callback(data);} //if specified, run callback on data returned
}
}
};
}
//-----------------------------------------------------------------------------
//Test execute above function with callback
getJSON('js/species.json', function(data){
console.log(data);
});
The console in Chrome is throwing this error:
"XMLHttpRequest cannot load file:///C:/Users/brett/Desktop/SightingsDB/js/species.json. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource."
Would be grateful for any insights - many thanks.
Basically as Felix, error msg, et al below say - simply can't run an AJAX request against a local file.
Thanks.
Try to run the application on local server like apache or wamp then you will not face any issue
i want to make a script that makes every video's comment section look like the ones that still have the old kind.
for example, videos on this channel:https://www.youtube.com/user/TheMysteryofGF/videos
in Firebug, in the Net tab, i noticed the comment JSON file's URL it is requested from is different.
i tried to run a code on the youtube watch page which would request the file the same way, but it doesnt work, and in firebug it says it was forbidden.
the URL is the same, they are both POST, and i cant figure out what is different. i can even resend the original request in firebug and it works... so anyway, here is a code i tried on a video with "1vptNpkysBQ" video url.
var getJSON = function(url, successHandler, errorHandler) {
var xhr = typeof XMLHttpRequest != 'undefined'
? new XMLHttpRequest()
: new ActiveXObject('Microsoft.XMLHTTP');
xhr.open('post', url, true);
xhr.onreadystatechange = function() {
var status;
var data;
// https://xhr.spec.whatwg.org/#dom-xmlhttprequest-readystate
if (xhr.readyState == 4) { // `DONE`
status = xhr.status;
if (status == 200) {
data = JSON.parse(xhr.responseText);
successHandler && successHandler(data);
} else {
errorHandler && errorHandler(status);
}
}
};
xhr.send();
};
getJSON('https://www.youtube.com/watch_fragments_ajax?v=1vptNpkysBQ&tr=time&frags=comments&spf=load', function(data) {
alert('Your public IP address is: ' + data);
}, function(status) {
alert('Something went wrong.');
});
You are using Ajax to get data. Ajax has 1 restriction: You can only get data from your own server. When you try to get data from another server/domain, you get a "Access-Control-Allow-Origin" error.
Any time you put http:// (or https://) in the url, you get this error.
You'll have to do it the Youtube way.
That's why they made the javascript API. Here is (the principal of) how it works. You can link javascript files from other servers, with the < script > tag
So if you could find a javascript file that starts with
var my_videos = ['foo', 'bar', 'hello', 'world'];
then you can use var my_videos anywhere in your script. This can be used both for functions and for data. So the server puts this (dynamically generated) script somewhere, on a specific url. You, the client website can use it.
If you want to really understand it, you should try building your own API; you'll learn a lot.
Secondary thing: Use GET.
POST means the client adds data to the server (example: post a comment, upload a file, ...). GET means you send some kind of ID to the server, then the server returns its own data to the client.
So what you are doing here, is pure GET.
I am grabbing some (random) images from a search machine and display them to the users. The problem is: It may happen that some images require a http authentification (username/password). I dont want to have those images... they should be removed without displaying the popup where you can enter the username and password.
Actually I am using simple jquery methods to display my images.
var displayNode = ....
....
var m_img = $("<img />", {src : "...."});
m_img.bind('error', function (e) {
$(this).remove();
});
displayNode.append(m_img);
Now I load the image directly and if an error occurs it will be removed. But.. when server sends back a HTTP (Basic) Authentification flag this is of course not an error. Hence there is an input prompt. When I click on "cancel" the propmt closes, jquery treats this as an error and removes the image.
So.. what is the best way to check if there is authentification and if not display it to the user?
You can make a HEAD request that only returns headers, then check the headers for the authentication header before actually making the request:
The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
You would use this method to first check the headers, then if OK, get the image. You'll have to test it with your protected resource, I'm not sure what the browser will do when requesting just the HEAD and I don't have a local protected resource to test against (CORS got me on the online resources I was trying to test against). Fiddle:
var basicAuthProtectedURL = 'http://fiddle.jshell.net';
var xhr = new XMLHttpRequest();
xhr.open("HEAD", basicAuthProtectedURL, true);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(xhr.getAllResponseHeaders()); //all headers
console.log(xhr.getResponseHeader('Content-Type')); //just the one you want
if (xhr.getResponseHeader('WWW-Authenticate')) {
console.log('I got the authentication header, skip this request.');
} else {
console.log('no header, resource unsecure');
}
} else {
console.error(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
xhr.send(null);
http://jsfiddle.net/5z5bnwgz/
Post back how it goes!
I have download documents from google drive by using Google drive API with java. But i want to use javascript instead of java. So i am using Drive API client libraries java script code.
i am using the below code for achieving this
function downloadFile(file, callback) {
if (file.downloadUrl) {
var accessToken = gapi.auth.getToken().access_token;
var xhr = new XMLHttpRequest();
xhr.open('GET', file.downloadUrl);
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.onload = function() {
callback(xhr.responseText);
};
xhr.onerror = function() {
callback(null);
};
xhr.send();
} else {
callback(null);
}
}
My problem is i can able to display all file names and contents. but i can't download the files. Do i need to do any extra code? How can i save the files in my local system. any suggestions ?
Note: i can get value in file.downloadUrl if i paste the downloadUrl in the browser it won't give any result ,just show a blank page.
"if i paste the downloadUrl in the browser it won't give any result" is correct because when you GET using a browser there is no authentication header. If you check the status you will see a 401 error.
I use "Authorization: 'OAuth ' + gapi.auth.getToken()['access_token']" rather than 'Bearer'. I'm not sure if that is significant.
Are you sure the downloadUrl is current? This is a short-lived attribute, so it's possible the link has expired.
It's also possible the access token is invalid. As Burcu said, your answer is probably within the response and status to your xhr get.
I tried using the example from Google Drive documentation.
So the code is :
var request = gapi.client.drive.files.delete({
'fileId' : someFileId
});
request.execute(function(resp)
{
console.log(resp);
});
The app is installed properly and I'm using drive.file scope.
The problem is that the file is not deleted. It is still present in the Drive UI and cannot be opened anymore or downloaded. File is corrupted.
The request being sent is not the DELETE https://www.googleapis.com/drive/v2/files/fileId as was stated in docs. It is a POST https://www.googleapis.com/rpc?key=API_KEY. The body contains a JSON array:
[{"jsonrpc":"2.0","id":"gapiRpc","method":"drive.files.delete","params":{"fileId":"someFileId"},"apiVersion":"v2"}]
Response contains one empty JSON object. There are no errors in the response and there are no JS errors in the page. The APIs Explorer successfully deletes the file.
Any hints?
Try a XMLHttpRequest instead:
var xmlReq = new XMLHttpRequest();
xmlReq.open('DELETE', 'https://www.googleapis.com/drive/v2/files/' + fileId + '?key=' + apiKey);
xmlReq.setRequestHeader('Authorization', 'Bearer ' + accessToken);