10

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?

Sheki
  • 1,597
  • 1
  • 14
  • 25
  • you can find the answer here: https://stackoverflow.com/questions/4545311/download-a-file-by-jquery-ajax – juanecabellob Oct 25 '17 at 12:29
  • @juancab jQuery file download seams to be not the solution, I can't even send my headers (Bearer Token), if I'm not wrong, jQuery. file download seams to be just a solution for that what I already solved and that's getting a save dialog. I din't tested but I think jQuery file download will have the same problem like I have, and that is downloading larger files than the RAM-memory, pleas correct me if I'm wrong. – Sheki Oct 25 '17 at 13:07

1 Answers1

1

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.

juanecabellob
  • 458
  • 3
  • 14
  • Thank you for your answer, I know about StreamSaver.js but I just can't believe that in the time where frameworks like angular and react are booming, (by whom the usage of AJAX is crucial) the only "solution" that one can find is one library that is supporting just chrome (Almost no one uses Opera)?! – Sheki Oct 25 '17 at 14:39