I'm trying to download large file using chrome and would like to use stream to pipe it to the filesystem so it won't consume browser's RAM. Examples that I found so far, as I understand preloads everything to the RAM, and then save it to the filesystem, like:
const link = document.createElement('a');
link.href = window.URL.createObjectURL(new Blob([byte], { type: 'text/csv' }));
link.download = reportName;
link.click();
Also I can't use <a href=http://... /> because I need to pass authorization header with my request.
Related
I have a script that receives a download link from an API request. If you click the link, it automatically downloads the file with no file extension. I need the script to return a CSV file. What is the simplest way of handling this?
In essence, I want the following Python code in JavaScript.
r = requests.get(base64ToString(get_log_files(getlog_ID("APIKEY"))['log_csv_url_b64']), allow_redirects=True)
open('flight.csv', 'wb').write(r.content)
This is the code I have now written in JavaScript, a language I am a complete novice in. Currently it downloads a blank CSV file to the user.
let blob = await response.blob();
let link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "flight.csv";
link.click();
I am using this code to download a DataURL to a file
function downloadURI(uri, name) {
var link = document.createElement("a");
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
delete link;
}
downloadURI(data, "images/helloWorld.png");
but it tries to download to user storage. I want to download to server storage (For example download to "images/download.png" rather than prompt the user to download on their computer.
I tried to pass into PHP but the dataurl is too large for ajax to pass through.
First of all, you need to create some backend code to download it on server storage. You might only need the URI from frontend, make a call on some backend API and then request everything from backend.
I have an amazon S3 URL being passed back to me from an external service that is in the format:
https://foo.s3.amazonaws.com/ProjectDownloads/foo/title.xlsx?AWSAccessKeyId=foo&Expires=1602279238&Signature=foo
I haven't worked much with S3, but my understanding is this is a Presigned URL - I can paste it in my browser and the excel file downloads.
How can I download this file directly using javascript (on the frontend, as my system is not running node)?
I have tried generating an tag element with click - however all my files download as corrupt. I can download the file directly by pasting the link in my browser and it auto initiates a download.
Any help will be appreciated.
I have tried the following, but it downloads a file with error:
var link = document.createElement('a');
link.href = url;
link.download = 'foo.xlsx';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
You don’t need JS to force a download on clicking the link; you can do this with just HTML. And, it doesn’t matter that the source is a presigned S3 URL - it works with any URL.
<a href=“Foo.xlsx” download>click to download</a> should do it for you.
Have a look at https://www.w3schools.com/howto/howto_html_download_link.asp for the browser support matrix.
I have a blob url and a button on my site. The user can click on that button and the blob opens in a new tab.
<a class="downloadlink" id="downloadlink" target="_blank" href="[[_blobUrl]]"></a>
This works.
If the user has the setting for the file type behind this blob (e.g. pdf) to save the file instead of previewing it in the browser, the file gets downloaded of course. But firefox creates a random filename of the format
[a-zA-Z0-9]{8}\.pdf
Chrome uses the blob uuid and appends pdf.
How can I control the filename AND respect the users preferences?
When I add the download attribute the file gets always downloaded, also when the user has the setting "Preview" for the specified file type. I want the behavior the user prefers (preview or download) but still control the filename in case the user prefers downloading the file.
Update for firefox:
I got a solution for firefox but it is not working in chrome. Instead of
this._blobUrl = URL.createObjectURL(blob);
I do
let file = new File([blob], this.downloadname, {type: 'application/pdf'});
this._blobUrl = URL.createObjectURL(file);
Chrome does expose this preference through the navigator.plugins dictionary. If this object contains a PDF Reader, then you know the user wants to see it displayed in their browser.
const opensInBrowser = [...navigator.plugins].some(plug => [...plug].some(mime => mime.type === 'application/pdf'))
console.log(opensInBrowser);
But this does only work for Chrome. Firefox doesn't expose this information here (IIRC they don't technically use a Plugin to display the pdf). So this means that we can't use only this; Firefox will always be marked as not opening in browser, while it may very well be.
So I think the only way is still a very long one... exposed in details here..
Using a Service Worker, we can fake a request to a named file, that Chrome will use to set the name, both of the downloaded file and of the pdf read by the plugin.
That is until they follow Firefox in forwarding correctly File objects names through the Blob URIs that point to them.
Simpliest solution (that should also work with IE10) is to create an a element, attach it to body, set it's name, let user download it and remove after, something like this:
function save(){
const file = new File(['this is where BLOB should go'], {type: 'application/pdf'}); // edit this line to have access to source blob
const link = document.createElement('a');
link.href = URL.createObjectURL(file);
link.download = 'this is the name.pdf';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
window.save = save;
and for HTML:
<a class="downloadlink" id="downloadlink" target="_blank" onclick='save()'>here is your link</a>
working example can be found here
take notice of:
you should edit the onclick function to pass the blob you're
expecting to be as an output of the file
in example i created a pdf only, however you can extend this
functionality pretty easily to any kind of document you need (and is
recognizable by given browser)
My Pdf file is stored in google bucket, and i have a link let say https://storage.googleapis.com/bucketName/xyz.pdf. To download this file i am doing this,
<a href="https://storage.googleapis.com/bucketName/xyz.pdf" download> Download This File </a>
But when i click on this anchor tag, instead of downloading this file browser open this file in same tab even i try to download the file via javascript and was using this code .
var link = document.createElement("a");
link.download = 'File.pdf';
link.href = 'https://storage.googleapis.com/bucketName/xyz.pdf';
link.click();
But same happen again file open in same tab instead of downloading. I don't know what is the main problem ? Is this Google bucket is not letting file to download, or my chrome setting preventing files to download.
It is not downloading in Chrome i guess Chrome do allow the downloading from CORS files.
As per JavaScript/jQuery to download file via POST with JSON data construct a blob and use that to return the file reference for the link.
This will inform the browser of your intent in a standards compliance manner.
example ...
$.get(/*...*/,function (result)
{
var blob=new Blob([result]);
var link=document.createElement('a');
link.href=window.URL.createObjectURL(blob);
link.download="myFileName.txt";
link.click();
});
Solution
Content-Disposition attachment seems to work for me:
self.set_header("Content-Type", "application/json")
self.set_header("Content-Disposition", 'attachment; filename=learned_data.json')
Workaround
application/octet-stream
I had something similar happening to me with a JSON, for me on the server side I was setting the header to
self.set_header("Content-Type", "application/json")
however when i changed it to:
self.set_header("Content-Type", "application/octet-stream")
It automatically downloaded it.
Also know that in order for the file to still keep the .json suffix you will need to it on filename header:
self.set_header("Content-Disposition", 'filename=learned_data.json')
Try link.target = "_blank"; this will open file in new tab and link.download will force it download.
Please tell if this works.