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.
Related
I've been following this Google File Picker tutorial and I've gotten so far as to get the file picker showing and getting the URL, but I don't know how to download the file using JavaScript. If I can use VB.NET, then can someone point me in the right direction?
I've been able to download files with VB.NET from my own database, but I don't know how to get it with the Google API or with JavaScript.
All of the file picker code works, and I'm calling this from the onSelect of the FilePicker:
function downloadGDriveFile(file) {
if (file.downloadUrl) {
var accessToken = gapi.auth.getToken().access_token;
var xhr = new XMLHttpRequest();
xhr.open('GET', file.downloadUrl); // use selfLink??
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.onload = function () {
var content = xhr.responseText;
};
xhr.onerror = function () {
alert('Download failure.');
};
xhr.send();
} else {
alert('Unable to download file.');
}
}
And when I click on the download URL I get this error:
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
The error you posted is an issue with your account reaching it's max usage limit. Different issue than downloading the file. I don't have any knowledge on the google file picker api, but I'm going to assume this is in the browser.
You may have to specify req.responseType = "arraybuffer" because it could default to json.
I recommend using http://danml.com/download.html. Browser API does not expose the download modal for security reasons. The hack is to create an invisible a tag set the url to the blob of the body that you received and programmatically click the tag. The library provided does exactly that.
I'm doing the JavaScript challenges at FreeCodeCamp. One of them is to create a web page that retrieves and displays weather information.
First, I tried to use several providers (e. g. OpenWeatherMap, WeatherUnderground), which use the HTTP protocol to return weather data. It didn't work because of the mixed content error.
Next, I switched to a provider, which delivers the data via HTTPS. I got rid of the mixed content problem, but got another one:
XMLHttpRequest cannot load https://api.weatherbit.io/v1.0/current?lat=55.7767723&lon=37.6090795&units=S&key=XXXXXXXX. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://s.codepen.io' is therefore not allowed access. The response had HTTP status code 403.
I tried to implement CORS according to this tutorial:
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// Otherwise, CORS is not supported by the browser.
xhr = null;
}
return xhr;
}
[...]
var url = "https://api.weatherbit.io/v1.0/current?lat=" + position.coords.latitude + "&lon=" + position.coords.longitude + "&units=S&key=XXXXXXXX";
var xhr = createCORSRequest('GET', url);
if (xhr) {
xhr.onload = function() {
var responseText = xhr.responseText;
console.log("Response: " + responseText);
};
xhr.onerror = function() {
console.log('There was an error!');
};
xhr.send();
}
When I call xhr.send() I still get the error.
How can I fix it?
Note: I'm looking for a solution that will run in CodePen.
Update 1 (23.03.2017 11:35 MSK): I tried to implement sideshowbarker's answer and modified the code like this:
function getCurrent(json){
console.log("getCurrent called");
console.log(json.data.temp);
console.log(json.data.precip);
}
function updateWeather() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var url = "https://api.weatherbit.io/v1.0/current?callback=getCurrent&lat=" + position.coords.latitude + "&lon=" + position.coords.longitude + "&units=S&key=XXXXXXXXX";
console.log("url: " + url);
$.get(url, function(val){});
});
} else {
console.log("Cannot obtain location data");
};
}
updateWeather();
The result:
Update 2 (23.03.2017 13:29 MSK): This one works.
function getCurrent(json) {
console.log("getCurrent called");
console.log(JSON.stringify(json));
// TODO: Update the UI here
}
function updateWeather() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var url = "https://api.darksky.net/forecast/XXXXXXXXX/37.8267,-122.4233?callback=getCurrent";
var script = document.createElement('script');
script.src = url;
document.getElementsByTagName('head')[0].appendChild(script);
});
}
}
updateWeather();
The Weatherbit.io API doesn’t support cross-origin requests made from XHR.
Instead the API requires you make the requests using a script element with a JSONP callback:
<script>
function getCurrent(json){
console.log(json.data.temp)
console.log(json.data.precip)
}
</script>
<script
src="https://api.weatherbit.io/v1.0/current?callback=getCurrent&lat=NNN&lon=NNN&units=S&key=XX"></script>
Of course you likely want to have your code inject that script element with the URL and params.
That’s method of injecting the script element with a JSONP callback is the only direct method they support for using their API from a web app.
There’s no way your code will work if it instead makes the request to their API using XHR; they don’t send the necessary Access-Control-Allow-Origin response header, and so because that’s missing, your browser won’t let your client-side JavaScript access the response cross-origin.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS explains why.
The only way you could use XHR to work with their API is if you set up a CORS proxy using code from https://github.com/Rob--W/cors-anywhere/ or something similar—or if you send your request through an public CORS proxy like https://github.com/Rob--W/cors-anywhere/ (which you don’t want to do because that’d give the owner of that service access to your Weatherbit.io API key).
The way the proxy works is that instead of using weatherbit.io URL, you use a proxy URL like https://cors-anywhere.herokuapp.com/https://api.weatherbit.io/v1.0/current…, and the proxy sends it on to weatherbit.io, gets the response back, then adds the Access-Control-Allow-Origin response header to the response it hands back to your code and that the browser sees.
I was in the process of completing the Weather App in FCC and came across the same issue. I was able to get it to work with the following line:
$.getJSON("https://api.weatherbit.io/v1.0/current?lat=##&lon=##&key=##", function(data){};
For whatever reason, it wouldn't work with just "http://", I had to change it to "https://" in order for it to work.
Not sure if that helps anyone in the future.
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 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);
I am attempting to download a file from Google Storage using the Javascript json api. I am able to retreive the object info by using the code below, however I'm not sure how to get the actual media. I'm familiar with the Java library method getMediaHttpDownloader, but I do not see an equivalent in JS. Any help would be appreciated!
gapi.client.storage.objects.get({"bucket":"bucketName","object":"objectName"});
The Javascript library does not currently support directly downloading media. You can still get to the data, but you'll have to access it another way.
Depending on the domain your website is hosted on and the bucket you're reading from, you'll need to set up CORS: https://developers.google.com/storage/docs/cross-origin
Then, you'll need to request the object directly via the XML API. For example, you could do something like this:
var accessToken = gapi.auth.getToken().access_token;
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://'+bucket+'.storage.googleapis.com/'+object);
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.send();
I've ended up not using the api(not sure that you can download using api, interested if you do know how) and using XmlHttpRequest instead. To do this I had to setup CORS for my google storage bucket to allow my site cross domain access. Below is my code:
var myToken = gapi.auth.getToken();
var req = new XMLHttpRequest;
req.open('GET','https://storage.googleapis.com/bucket/object',
true);
req.setRequestHeader('Authorization', 'Bearer ' + myToken.access_token);
req.send(null);
I did it using gapi and jQuery.
In my case object is public. (pulbic link in storage browser must be checked). In case you don't want your object to be public, use $.post instead of $.get and provide assess_token as header exactly as it is done in other answers.
Storage.getObjectInfo retrieves object metadata.
Storage.getObjectMedia retrieves object content.
var Storage = function() {};
Storage.bucket = 'mybucket';
Storage.object = 'myfolder/myobject'; //object name, got by gapi.objects.list
Storage.getObjectMedia = function(object, callback) {
function loadObject(objectInfo) {
var mediaLink = objectInfo.mediaLink;
$.get(mediaLink, function(data) { //data is actually object content
console.log(data);
callback(data);
});
}
Storage.getObjectInfo(object, loadObject);
};
Storage.getObjectInfo = function(object, callback) {
var request = gapi.client.storage.objects.get({
'bucket' : Storage.bucket,
'object' : Storage.object
});
request.execute(function(resp) {
console.log(resp);
callback(resp);
});
};
It is also relatively rare case when we need to download the content of object. In most cases objects stored in Storage are media files like images and sounds and then all what we need is actually mediaLink, which must be inserted to src attribute value of appropriate dom element (img or audio).