前端JS 下載大檔案解決方案
阿新 • • 發佈:2020-07-03
## 問題場景
點選匯出按鈕,提交請求,下載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 = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", false, false);
link.dispatchEvent(evt);//釋放URL 物件
document.body.removeChild(link);
}
}).catch((error) => {
console.log(error)
})
```
這種方式是把檔案流讀取到瀏覽器記憶體中,再下載,但是今天在這種大檔案場景下它不香了,
由於記憶體過大,直接把網頁給搞崩了,喔豁:joy:
![](https://img2020.cnblogs.com/blog/1619281/202007/1619281-20200702224045623-1391402897.jpg)
怎麼辦呢,終於在Github上找到了一個大神的庫,用起來真香,[Github地址](https://github.com/eligrey/FileSaver.js)
根據介紹,在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 閘道器超時錯誤,注意配置Nginx
* 控制檯報error response,瀏覽器請求長時間得不到響應,本地除錯代理轉發超時造成的,[參考](https://segmentfault.com/q/1010000017751671)
* [檔案超過2G的解決方案](https://github.com/eligrey/FileSaver.js/issues/163
)