這里與后端已經約定好了,成功有文件流時返回staus為0
問題:當下載文件時,axios配置responseType: ‘blob’,此時后台返回的數據會被強制轉為blob類型;如果后台返回失敗對象,前端也無法得知,如果按正常處理會得到名為undefined的文件。
解決:在try代碼塊里面嘗試將axios已經轉成blob格式的res轉回json格式,如果不報錯說明服務端返回的是對象,表示下載失敗,提示出后端返回的錯誤;如果進入catch說明返回的是二進制流。
具體代碼如下(這里的提示使用的是elementUI提供的message,下載的文件是壓縮包文件,也可以根據需求修改文件類型):
// 點擊下載事件 async downloadFile() {var that = this; axios({ method: 'post', url: '', data: this.searchForm, responseType: 'blob', }) .then((res) => { const data = res.data; // 有可能下載失敗,比如返回{status: 0},但設置了responseType: 'blob',axios會把data強制轉為blob,導致下載undefined.excel(后綴取決於文件類型,這里只是舉例) // 解決:將已轉為blob類型的data轉回json格式,判斷是否下載成功 const r = new FileReader(); r.onload = function () { // 如果JSON.parse(this.result)不報錯,說明this.result是json字符串,則可以推測是下載報錯情況下返回的對象,類似於{status: 0} // 如果JSON.parse(this.result)報錯,說明是下載成功,返回的二進制流,則進入catch進行后續處理 try { const resData = JSON.parse(this.result); // this.result為FileReader獲取blob數據轉換為json后的數據,即后台返回的原始數據 // 如果執行到這里,說明下載報錯了,進行后續處理 if(resData.status !== 0) { that.$message({ message: resData.statusText, type: 'warning', }); } } catch (err) { // 下載正常處理 that.$message({ message: '文件下載中', type: 'success', }); let blob = new Blob([res.data], { type: 'application/zip' }); //如果文件是excel,把type換成 type: 'application/vnd.ms-excel' 即可
let url = window.URL.createObjectURL(blob); const link = document.createElement('a'); // 創建a標簽 link.href = url; link.download = '文件名'; // 重命名文件 link.click(); URL.revokeObjectURL(url); // 釋放內存 } }; r.readAsText(data); // FileReader的API }) .catch((res) => { console.log(res); that.$message.error('下載失敗'); }); },
這樣就可以啦!