之前因爲懶,異步請求的下載都是直接寫在a標籤裏,請求權限讓後端做特殊處理判斷,就像這樣
<a href="getRequestUrl">點擊下載</a>
現在覺得這樣處理不太好,一個是後端權限要做單獨判斷,另一個是如果調用接口報錯就沒辦法處理了,研究之後修改了一下,項目用了axios這個lib,所以是針對axios的request和response做了修改,不過對於原生寫法和其他庫,原理是一樣的
1.將請求的responseType設置爲blob
function exportData(p) {
axios({
url: '/data/export',
method: 'get',
params: p,
responseType: 'blob'
});
}
2.對response進行處理
因爲項目裏用了response攔截器來處理響應,所以我在攔截器裏做了處理,也可以單獨處理。
axios.interceptors.response.use(
response=> {
// ...
// Blob類型處理
let checkType = response.config.responseType;
if(checkType === "blob" && res.type === 'application/octet-stream') { // 正常下載時直接返回響應數據
return response.data
} else if(checkType === "blob" && res.type === 'application/json') { // 請求出錯時,接口返回的內容是json,於是將blob中的內容取出
let reader = new FileReader();
reader.onload = function(event){
let content = reader.result; // blob中的內容
Message({
message: JSON.parse(content).desc,
type: 'error',
duration: 5 * 1000
})
};
reader.readAsText(response.data);
return Promise.reject('error')
}
// ...
},
error => {
// ...
}
)
3.html頁面自動開始下載
exportData(para).then(res => {
let content = res;
let aTag = document.createElement('a');
let blob = new Blob([content]);
aTag.download = 'Datas.xlsx'; // 也可以讓後端設置文件名,通過headers返回
aTag.href = URL.createObjectURL(blob);
aTag.click();
URL.revokeObjectURL(blob);
}).finally(() => {
})
參考博客:https://www.cnblogs.com/coder...