前端JS下载⼤⽂件解决⽅案
问题场景
点击导出按钮,提交请求,下载excel⼤⽂件(超过500M),该⽂件没有预⽣成在后端,
直接以⽂件流的形式返回给前端。
解决⽅案
在Vue项⽬中常⽤的⽅式是通过axios配置请求,读取后端返回的⽂件流,常⽤代码如下:
axios({
method: 'post',
url: 'api/file',
responseType: 'blob'
}).then(res=> {
if (res.data){
filename = 'filename';
let blob = new Blob([res.data],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"}); if (window.navigator.msSaveOrOpenBlob){
// IE10+下载
navigator.msSaveOrBlob(blob, filename);
}else{
// ⾮IE10+下载
let link = ateElement('a');
link.href = ateObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
var evt = ateEvent("MouseEvents");
evt.initEvent("click", false, false);
link.dispatchEvent(evt);//释放URL 对象
veChild(link);
}
}).catch((error) => {
console.log(error)
})
这种⽅式是把⽂件流读取到浏览器内存中,再下载,但是今天在这种⼤⽂件场景下它不⾹了,
由于内存过⼤,直接把⽹页给搞崩了,喔豁
怎么办呢,终于在Github上到了⼀个⼤神的库,⽤起来真⾹,
根据介绍,在chrome浏览器2G以下的⽂件下载可以得到很好的⽀持
使⽤步骤
1.安装npm依赖
npm install file-saver --save
2.引⼊代码
+ import { saveAs } from 'file-saver';
...
+ saveAs(blob, fileName );
3.完整例⼦
+ import { saveAs } from 'file-saver';
axios({
method: 'post',
url: 'api/file',
responseType: 'blob'
}).then(res=> {
if (res.data){
fileName = this.fileName;
// 有⽂件名就⽤⾃定义的,没有就从header获取
if (!fileName) {
fileName = fileNameFromHeader(
res.headers["content-disposition"] || ""
);
}
let blob = new Blob([res.data],{
type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"});
+ saveAs(blob, fileName );
}
}).catch((error) => {
console.log(error)
})
function fileNameFromHeader(disposition) {
let result = null;
disposition = disposition.split(";")[1];
if (disposition && /filename=.*/gi.test(disposition)) {
result = disposition.match(/filename=.*/gi);
return decodeURIComponent((result[0].split("=")[1]).replace(/\+/g, '%20'));
}
return "null";
}
4.其他问题
下载⼤⽂件过程中遇到的其他问题
axios请求超时,注意配置timeout
Nginx 响应超时报504 ⽹关超时错误,注意配置Nginxnginx部署前端项目
控制台报error response,浏览器请求长时间得不到响应,本地调试代理转发超时造成的,
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论