如何使用 JavaScript 下载大文件

Posted

技术标签:

【中文标题】如何使用 JavaScript 下载大文件【英文标题】:How to download large file with JavaScript 【发布时间】:2018-04-06 12:44:54 【问题描述】:

我需要使用 XMLHttpRequest 或 fetch 使用 javascript 下载一个大文件,而无需先将文件保存在 RAM 内存中。

普通链接下载对我不起作用,因为我需要在请求的标头中发送承载令牌。

我可以设法下载一个文件,但是这个“解决方案”,它首先将文件保存在 RAM 内存中,然后我得到一个保存对话框,这样如果文件大于可用 RAM,浏览器就会停止-内存。

这是我使用 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();
            );

这是我使用 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();

问题是如何下载大于可用 RAM 内存的文件并同时设置标题?

【问题讨论】:

你可以在这里找到答案:***.com/questions/4545311/… @juancab jQuery 文件下载接缝不是解决方案,如果我没记错的话,我什至无法发送我的标头(承载令牌)。文件下载接缝只是我已经解决的解决方案,并且正在获得一个保存对话框。我没有测试过,但我认为 jQuery 文件下载会遇到和我一样的问题,那就是下载的文件比 RAM 内存大,如果我错了,请纠正我。 【参考方案1】:

如 StreamSaver.js(下面的链接)中所示,您可以使用流来解决此问题。

你可以试试StreamSaver.js(免责声明:我不是那个回购的所有者)。似乎可以解决您想要的问题,因为它不是跨浏览器兼容的。目前仅 Chrome +52 和 Opera +39 支持。

另外,还有FileSaver.js(免责声明:我不是该回购协议的所有者),但您会遇到当前遇到的相同问题。

【讨论】:

感谢您的回答,我知道 StreamSaver.js,但我无法相信在 Angular 和 React 等框架蓬勃发展的时代,(AJAX 的使用至关重要)唯一能找到的“解决方案”是一个只支持 chrome 的库(几乎没有人使用 Opera)?!

以上是关于如何使用 JavaScript 下载大文件的主要内容,如果未能解决你的问题,请参考以下文章

如何缓存使用脚本标签下载的已下载 javascript 文件

如何使用 Javascript 下载、压缩和保存多个文件并取得进展?

如何在Python中下载大文件?

如何在ios中恢复大文件的下载

如何使用 Javascript 创建和下载 csv 文件?

如何使用 PHP 下载大文件?