目錄
前言:
采坑之路
總結:
前言:
近日,項目中踩了一個坑分享一下經驗,也避免下次遇到方便解決。項目基于vue2+axios+element-ui,業務中導出按鈕需要直接下載接口中的文件流。正常是沒有問題,但是測試確測出來參數正確時,后端接口沒有返回文件流,而是報錯提示。返回結果集如圖:
采坑之路
1.正常接口返回result里就直接輸出message,然后顯示錯誤提示就好了。
問題是我們用的axios中post請求的,responseType:"blob"類型設置死了,接收的只有文件流相關信息,打印了res,沒有后端的返回錯誤碼:
這就尷尬了,原邏輯不管數據是不是都該返回一個二進制文件流的內容來下載,即使是個空文件是吧。但是遇到這個錯誤提示,就得解決啊。
2.尋求網上方法,最終填坑完成,分享一下這個完整解法:
this.axios.post('/zzh/afterSale/exportAfterSaleMaintainForm', JSON.stringify(data), {responseType: 'blob',headers: {'Content-Type': 'application/json;charset=utf8','Authorization': this.$store.state.user.token,'Language': this.lan,},}).then(function (res) {// responseType: 'blob' 這個類型獲取報錯提示if(res.data.success===undefined && res.data.type === 'application/json'){const fileReader = new FileReader()fileReader.readAsText(res.data,'utf-8')fileReader.onload = function(){const result = JSON.parse(fileReader.result)_this.$message.error(_this.$t('errorCode.' + result.code)); // 業務中拼接報錯提示}return}const content = res.dataconst blob = new Blob([content], {type: "application/octet-stream"}) //構造一個blob對象來處理數據const encodeFileName = res.headers['content-disposition'].split(';')[1].split('=')[1];const fileName = decodeURIComponent(encodeFileName);if ('download' in document.createElement('a')) { //支持a標簽download的瀏覽器const link = document.createElement('a') //創建a標簽link.download = fileName //a標簽添加屬性link.style.display = 'none'link.href = URL.createObjectURL(blob)document.body.appendChild(link)link.click() //執行下載URL.revokeObjectURL(link.href) //釋放urldocument.body.removeChild(link) //釋放標簽} else { //其他瀏覽器navigator.msSaveBlob(blob, fileName)}})
總結:
1.首先遇到responseType:"blob"這個類型時,考慮報錯提示,需要把返回的數據轉成文件讀取錯誤提示;其中重要的是new FileReader()的使用。
2.文件下載的方法,組裝成二進制流文件,注意獲取content-disposition中文件名,否則下載的文件會是損壞的!其中重要的是 new Blob()的使用,創建對象A標簽,模擬點擊下載文件。