Andy's blog

If you always do what you've always done, you'll always get what you've always got.

0%

2021-06-09-利用axois來下載檔案

最近公司專案上剛好碰到製作匯出報表模組開發,而過往我都是透過form submit方式直接將參回拋給Controller,但當我列印發生問題時,
我無法由前台正確得知我正確的錯誤訊息為何,因為我的錯誤訊息只會有一組Default文字。而這次因為這個模組開發需要支援多國語系,因此在錯誤訊息方面
我就不能在前端hard code。我必須依照不同語系轉換錯誤語言跟錯誤內容。所以就藉此來研究一下該如何透過axios來下載檔案,並回傳正確錯誤訊息。


參考資料:
Convert Blob to String in JavaScript

用Javascript替中文網址轉碼

axios设置responseType===blob导出文件和失败返回json处理

Blob-MDN

使用axios如何下载文件

一、前提:
下載檔案時,Server會回拋資料串流。而一般axios未設定時,預設就為json格式。如果要下載檔案就必須在回傳型態指
{ responseType: 'blob' }才能正確接到資料!

二、接著,我們要判斷下載資料是否為空,這是後我們可以透過下面這段程式碼來判斷

1
2
3
4
5
6
7
// 因為我的回傳錯誤訊息內容的型態是json,所以假使我接到資料是json格式,及代表我匯出發生問題勒
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
//1.先宣告取得blob型態
const blb = new Blob([res.data], { type: "json" });
let reader = new FileReader();
//3.完全讀完才會進入
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);
}
}
};
//2.再將blb型態讀出來
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;

//透過decodeURI 將UTF-8轉碼
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")) {
//1.先宣告取得blob型態
const blb = new Blob([res.data], { type: "json" });
let reader = new FileReader();
//3.完全讀完才會
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);
}
}
};
//2.再將blb型態讀出來
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();
//document.removeChild('a');
}


}).catch((error) => {
if (error.response) {
alert(error.response.data);
} else {
alert(error.message);
}
});