gdrive javascript sdk download url - javascript

I'm using this code snippet from gDrive SDK for javascript to download file :
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);
}
}
How can i prompt the browser to open the download window when the ajax request is done. How to make the callback function in order to open the dialog for saving the file locally ?

Unfortunately, your approach won't work.
Because of standard browser security constraints, you can't save a file from Javascript.[1]
What you need to do is use the downloadUrl in a new window or src for an iframe to cause the browser to download the file, and prompt the user to save it. You will need to add
&access_token=ya29.YOURACCESSTOKENHERE
to the URL to avoid a 401 error.
Notes
1. Yes I know that HTML5 is starting to support limited filesystem access from Javascript, but (1) it's not widely available, (2) has restrictions on where the file can be saved, and (3) isn't the UX that the OP was asking for.

Related

xmlHttpRequest GET for responseType arraybuffer gets empty response in electron

I am using electron version 1.7.9.
I need to download a zip file in my app.
Following code is used for the same.
var urlFetch = <path to the zip file I want to download>
var xhr = new XMLHttpRequest();
xhr.open('GET', urlFetch, true);
xhr.responseType = "arraybuffer";
xhr.onloadend = function () {
var status = xhr.status;
if (status == 200) {
if (undefined !== xhr.response) {
successCallback(xhr.response);
} else {
failureCallback();
}
} else {
console.error("Failed to fetch " + urlFetch + ", status - " + status);
failureCallback();
}
};
xhr.send();
On Windows 10 as well as on MacOs HighSierra, this code always gets undefined xhr.response in spite of status being 200.
xhr.responseText is populated with string, but what I need is the binary data of the zip file that I can use to store into a file for further use.
I have also tried adding following, but with no success.
xhr.setRequestHeader("Content-Type", "application/zip");
Is there anything missing in the way I am coding or is this a bug in electron/chrome etc.?
The same code works perfectly outside of electron in a stand alone HTML.
The problem was with the node js module xmlHttpRequest which was included.
Things started working when I removed this module.
I was not able to see the XHR requests in the "network" tab of dev tools in my electron app.
After removing the module, I can now see the requests and things work as desired.

Ajax Call loads a Json File using FTP , Need to show Percentage load progress Bar

I'm using jQuery ajax to load a file kept in FTP server. Need to show percentage of file loaded in Progress loader.
Previously I had HTTP request and using XMLHttpRequest worked. Below is the code that worked.
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
// Upload progress
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total)*100;
var loadPercent = '<div id="fountainTextG">'+Math.round(percentComplete)+'% complete ..</div>';
$(".sqlLoading").html(loadPercent).removeClass("hide");
jsAPP.sqlLoading = true;
}
}, false);
// Download progress
xhr.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete =(evt.loaded / evt.total)*100;
var loadPercent = '<div id="fountainTextG">'+Math.round(percentComplete)+'% complete ..</div>';
$(".sqlLoading").html(loadPercent).removeClass("hide");
jsAPP.sqlLoading = true;
}
}, false);
return xhr;
},
type: 'POST',
url:'ftp://192.168.1.157/pub/1.json',
dataType: "jsonp",
jsonpCallback:"abc",
success: function(obj){
console.log("File loaded successfully");
},
error:function(err,stat,erroT){
$(".page").html("<div class='data_error'> Sorry! No data available for this city.</div>");
}
});
But this doesn't work on FTP request. Is there any way to show progress loader on FTP ? Kindly Help.
Here is my take on this question after I tried & tested three ways of accessing the file via js.
XMLHttpRequest
Although XMLHttpRequest states it it supports other protocols, it
doesn't seem to access a file served via ftp.
When I tried accessing using the code below, I hit a CORS error as
expected.
XMLHttpRequest cannot load ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
The FTP server doesn't seem to serve access control headers, also corroborated by the
post
testFtpLoad : function(){
var xhr = new XMLHttpRequest();
xhr.open("GET", "ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt", true);
xhr.onload = function (e) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(xhr.responseText);
} else {
console.error(xhr.statusText);
}
}
};
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
xhr.send(null);
},
Anchor tag
If you are using a modern browser, you could directly feed the ftp to the user using the download attribute (It's a simple <a> tag usage), although this is not what you are looking for.
testUsingAnchorTag : function(){
var $aTag = document.createElement("a");
$aTag.href = "ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt";
$aTag.id = "temporaryDownloadLink";
$aTag.download = "rfc959.txt";
document.body.appendChild($aTag);
$aTag.click();
setTimeout(function(){
$('#temporaryDownloadLink').remove();
}, 1000);
}
Downside: Though this downloads the file on the user's computer, you
will not be able to track it's progress
File API
I tried accessing the file using the FTP URL but it complained about
the parameters I passed.
var f = new File("ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt", true)
Even if I were to be successful in passing the right set of params,
it would have complained about the nature of URL since it only
expects a path served by server/from user's computer as mentioned in
this post - correct me if I'm wrong here.
Conclusion:
Finally I'd like to conclude that it may not be possible to serve &
track the progress of a file via FTP from the browser using js
You might have to fallback to your HTTP protocol and serve the files via a server over HTTP to achieve your goal
I've linked to most of the resources that I rummaged through- here are a few more.
Browser event of a download
detect-when-browser-receives-file-download
how-can-i-simulate-an-anchor-click-via-jquery
Sample ftp url
online
File API Documentation
Hope this helps.

XMLHttpRequest, send and security restrictions

I thought I could catch an error in send like this
try {
xhr.send();
} catch(e) {
// fix-me: With the
// bookmarklet on a https page
// you can't even send a HEAD
// request due to security
// restrictions. Check for
// this case here.
console.log("xhr.send, e=", e, method, window.location.href, url)
debugger;
}
console.log("I am here now");
However I never get to that console.log statement in the catch block after xhr.send.
In the console I instead get a message like this.
Mixed Content: The page at 'about:blank' was loaded over HTTPS,
but requested an insecure XMLHttpRequest endpoint 'http://m.org/'.
This request has been blocked; the content must be served over HTTPS.
I am here now.
Is it supposed to work this way? (I am using Google Chrome.)
Is there any way to find out that there was an error? (Except looking in the console. ;-) )
UPDATE
#giuscri added the very good question if I did consider that this is async. I actually missed that it could be, but it is not. A bit surprisingly. ;-)
Please see the this example. It contains this code:
var url = "http://nowhere.org/";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
console.log("onreadystatechance, readyState=", xhr.readyState);
};
xhr.onprogress = function(event) {
console.log("onprogress, readyState=", xhr.readyState);
console.log("onprogress, event=", event);
};
xhr.onerror = function(event) {
console.log("onerror, readyState=", xhr.readyState);
console.log("onerror, event=", event);
};
var method = "HEAD";
xhr.open(method, url, true);
try {
xhr.send();
} catch(e) {
console.log("xhr.send, e=", e, method, window.location.href, url);
}
console.log("After send");
When you run this page from https:// (as in the link above) the onerror function is not run. If you run the same example from file:// then onerror is run.
Connecting from HTTPS to HTTP URIs drops the security given by the underlying encryption. Web browsers blocks such requests until explicitly allowed by the user in order to prevent data leakage over plaintext connections. Further, there is also a change in origin (scheme, domain, port).
I allowed Mixed Content for the page you linked and I got the error about the different origin in console. Looks like the code works.
By the way, support for synchronous requests using XMLHttpRequest is deprecated, because it blocks user interaction until the request completes.

Openstack Swift - Trying to download a blob using Javascript

I have a problems downloading and saving locally the content of a blob from a container through the browser. Uploading a blob to a container worked properly but I can't download it using Firefox or Chrome. The only thing I achieved was retrieving the content in the reponse (Firefox) and I could download it only because of the Chrome cache (that is not valid for me). This is the code I am using:
<script type="text/javascript">
function uploadFile() {
var token = 'AUTH_AAAAAAAA';
var method = 'GET';
var url = 'http://ip/v1/AUTH_account/containerName/blobName';
var xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.setRequestHeader('X-Auth-Token', token);
xhr.setRequestHeader('accept', 'application/octet-stream');
xhr.send();
}
</script>
I cannot just use
<a href='http://ip/v1/AUTH_account/containerName/blobName' onclick='javascript:uploadFile();'>Blob to download</a>
because this link needs the Auth Token and it would respond with a "401 Unauthorized" message.
Thanks for your help.

JavaScript/jQuery check broken links

I developed a small Javascript/jQuery program to access a collection of pdf files for internal use. And I wanted to have the information div of a pdf file highlighted if the file actually exist.
Is there a way to programmatically determine if a link to a file is broken? If so, How?
Any guide or suggestion is appropriated.
If the files are on the same domain, then you can use AJAX to test for their existence as Alex Sexton said; however, you should not use the GET method, just HEAD and then check the HTTP status for the expect value (200, or just less than 400).
Here's a simple method provided from a related question:
function urlExists(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
callback(xhr.status < 400);
}
};
xhr.open('HEAD', url);
xhr.send();
}
urlExists(someUrl, function(exists) {
console.log('"%s" exists?', someUrl, exists);
});
Issue is that JavaScript has the same origin policy so you can not grab content from another domain. This won't change by upvoting it (wondering about the 17 votes).
I think you need it for external links, so it is impossible just with .js ...
If the files are not on an external website, you could try making an ajax request for each file. If it comes back as a failure, then you know it doesn't exist, otherwise, if it completes and/or takes longer than a given threshold to return, you can guess that it exists. It's not always perfect, but generally 'filenotfound' requests are quick.
var threshold = 500,
successFunc = function(){ console.log('It exists!'); };
var myXHR = $.ajax({
url: $('#checkme').attr('href'),
type: 'text',
method: 'get',
error: function() {
console.log('file does not exist');
},
success: successFunc
});
setTimeout(function(){
myXHR.abort();
successFunc();
}, threshold);
You can $.ajax to it. If file does not exist you will get 404 error and then you can do whatever you need (UI-wise) in the error callback. It's up to you how to trigger the request (timer?) Of course if you also have ability to do some server-side coding you can do a single AJAX request - scan the directory and then return results as say JSON.
Like Sebastian says it is not possible due to the same origin policy. If the site can be published (temporarily) on a public domain you could use one of the link checker services out there. I am behind checkerr.org
As others have mentioned, because of JavaScript's same origin policy, simply using the function from the accepted answer does not work. A workaround to this is to use a proxy server. You don't have to use your own proxy for this, you can use this service for example: https://cors-escape.herokuapp.com (code here).
The code looks like this:
var proxyUrl = "https://cors-anywhere.herokuapp.com/";
function urlExists(url, callback) {
var sameOriginURL = proxyUrl + url;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
callback(xhr.status < 400);
}
};
xhr.open('HEAD', sameOriginURL);
xhr.send();
}
urlExists(someUrl, function(exists) {
console.log('"%s" exists?', someUrl, exists);
});

Categories

Resources