最近公司專案上剛好碰到製作匯出報表模組開發,而過往我都是透過form submit
方式直接將參回拋給Controller
,但當我列印發生問題時,
我無法由前台正確得知我正確的錯誤訊息為何,因為我的錯誤訊息只會有一組Default文字。而這次因為這個模組開發需要支援多國語系,因此在錯誤訊息方面
我就不能在前端hard code
。我必須依照不同語系轉換錯誤語言跟錯誤內容。所以就藉此來研究一下該如何透過axios
來下載檔案,並回傳正確錯誤訊息。
參考資料:
Convert Blob to String in JavaScript
用Javascript替中文網址轉碼
axios设置responseType===blob导出文件和失败返回json处理
Blob-MDN
一、前提:
下載檔案時,Server會回拋資料串流。而一般axios未設定時,預設就為json格式。如果要下載檔案就必須在回傳型態指
{ responseType: 'blob' }
才能正確接到資料!
二、接著,我們要判斷下載資料是否為空,這是後我們可以透過下面這段程式碼來判斷
1 2 3 4 5 6 7
| if (res.headers["content-type"].includes("application/json")){ } else{ }
|
三、再來錯誤訊息部分,由於我們接到的型態是{ responseType: 'blob' }
所以我們必須將blob轉回json字串,如此才能回拋錯誤訊息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const blb = new Blob([res.data], { type: "json" }); let reader = new FileReader();
reader.onload = e => { if (e.target.readyState === 2) { let res = {}; res = JSON.parse(e.target.result); if (res.Msg.indexOf("app.") !== -1) { alert(i18n.t(res.Msg)); } else { alert(res.Msg); } } };
reader.readAsText(blb);
|
四、最後,則是檔案匯出的檔名跟匯出方式
1 2 3 4 5 6 7 8 9 10
| const url = window.URL.createObjectURL(new Blob([res.data])); const link = document.createElement('a'); link.href = url;
const fileName = decodeURI(res.headers["content-disposition"].split(" ")[1].replace("filename*=UTF-8''", ""));
link.setAttribute('download', fileName); document.body.appendChild(link); link.click();
|
五、完整程式碼如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| axios.post(url, postData, { responseType: 'blob' }).then((res, fileName) => { if (res.headers["content-type"].includes("application/json")) { const blb = new Blob([res.data], { type: "json" }); let reader = new FileReader(); reader.onload = e => { if (e.target.readyState === 2) { let res = {}; res = JSON.parse(e.target.result); if (res.Msg.indexOf("app.") !== -1) { alert(i18n.t(res.Msg)); } else { alert(res.Msg); } } }; reader.readAsText(blb); } else { const url = window.URL.createObjectURL(new Blob([res.data])); const link = document.createElement('a'); link.href = url; const fileName = decodeURI(res.headers["content-disposition"].split(" ")[1].replace("filename*=UTF-8''", "")); link.setAttribute('download', fileName); document.body.appendChild(link); link.click(); }
}).catch((error) => { if (error.response) { alert(error.response.data); } else { alert(error.message); } });
|