我們都知道下載文件有一種很簡單的方法:window.open(url),但是window.open(url)只是一個純粹的訪問下載文件的鏈接,並不能滿足所有下載文件的需求。
1.前端下載文件有時候會根據權限去下載(需要獲取登錄的token)
2.有時后端提供的是post請求的接口
3.自定義文件名
這時就需要用到blob啦:
Blob 對象表示一個不可變、原始數據的類文件對象。Blob 表示的不一定是JavaScript原生格式的數據
方法:
在請求頭部添加responseType:"blob"
responseType屬性是一個枚舉類型的屬性,返回響應數據的類型。它允許我們手動的設置返回數據的類型。
當下載文件時,axios配置responseType: ‘blob’,此時后台返回的數據會被強制轉為blob類型;如果后台返回代表失敗的data,前端也無法得知,依然會下載得到名為undefined的文件。
解決:將blob轉回json格式,通過code判斷是否下載成功
axios配置:(angular調用)
axios({ method: 'post', url: '/beisenassess/getExamDetailByCandidateId', responseType: 'blob', }) .then(res => { // 假設 data 是返回來的二進制數據 const data = res.data const jsonData = JSON.parse(res) if(jsonData.code !='200'){ alert('下載失敗') return } const url = window.URL.createObjectURL(new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"})) //以本地方式保存文件 if(window.navigator && window.navigator.msSaveOrOpenBlob){ window.navigator.msSaveOrOpenBlob(new Blob([data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}), '下載文件.xlsx'); }else{ const link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', '下載文件.xlsx') document.body.appendChild(link) link.click() document.body.removeChild(link) window.URL.revokeObjectURL(url) } });
ajax的調用:
$('#export').on('click',function(){
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.setRequestHeader('Content-type','application/json');
xhr.responseType = 'blob';
xhr.onload = () => {
if (xhr.status === 200) {
//var blob = xhr.response;
var blob=new Blob([this.response],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
filename='下載文件.xlsx';
//ie
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, filename);
} else {
const link = document.createElement('a');
const body = document.querySelector('body');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
// fix Firefox
link.style.display = 'none';
body.appendChild(link);
link.click();
body.removeChild(link);
window.URL.revokeObjectURL(link.href);
}
}
}
xhr.send();
});
