I need to download a large file with JavaScript using XMLHttpRequest or fetch without saving the file first in the RAM-Memory.
Normal link download doesn't work for me, because I need to send a Bearer Token in the header of the request.
I could manage to download a file, but this "solution", it's saving the file first in the RAM-Memory, before I get a save dialog, so that the Browser will brake if the file is larger then the available RAM-Memory.
Here is my "solution" with fetch:
var myHeaders = new Headers();
myHeaders.append('Authorization', `Bearer ${token}`);
var myInit = { method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default' };
var a = document.createElement('a');
fetch(url,myInit)
.then((response)=> {
return response.blob();
})
.then((myBlob)=> {
a.href = window.URL.createObjectURL(myBlob);
var attr = document.createAttribute("download");
a.setAttributeNode(attr);
a.style.display = 'none';
document.body.appendChild(a);
a.click();
a.remove();
});
And here is my "solution" with XMLHttpRequest:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = ()=>{
if (xhttp.readyState == 4){
if ((xhttp.status == 200) || (xhttp.status == 0)){
var a = document.createElement('a');
a.href = window.URL.createObjectURL(xhttp.response); // xhr.response is a blob
var attr = document.createAttribute("download");
a.setAttributeNode(attr);
a.style.display = 'none';
document.body.appendChild(a);
a.click();
a.remove();
}
}
};
xhttp.open("GET", url);
xhttp.responseType = "blob";
xhttp.setRequestHeader('Authorization', `Bearer ${token}`);
xhttp.send();
The question is how can I download files larger then the available RAM-Memory and in the same time setting the headers?
Creating the download linkCreate an object URL for the blob object. Create an anchor element ( <a></a> ) Set the href attribute of the anchor element to the created object URL. Set the download attribute to the filename of the file to be downloaded.
Most files: Click on the download link. Or, right-click on the file and choose Save as. Images: Right-click on the image and choose Save Image As. Videos: Point to the video.
As found in StreamSaver.js (link below), you could work with streams to workaround this issue.
You can try StreamSaver.js (Disclaimer: I am not the owner of that repo). Seems to solve what you want to the extent that it is not cross-browser compatible. Currently it is only supported by Chrome +52 and Opera +39.
Alternatively, there is FileSaver.js (Disclaimer: I am not the owner of that repo) but you'd run into the same problems you are currently running into.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With