iT邦幫忙

0

利用axois來下載檔案

前言:

最近公司專案上剛好碰到製作匯出報表模組開發,而過往我都是透過form submit方式直接將參回拋給Controller,但當我列印發生問題時,我無法由前台正確得知我正確的錯誤訊息為何,因為我的錯誤訊息只會有一組Default文字。

而這次因為這個模組開發需要支援多國語系,因此在錯誤訊息方面
我就不能在前端hard code。我必須依照不同語系轉換錯誤語言跟錯誤內容。所以就藉此來研究一下該如何透過axios來下載檔案,並回傳正確錯誤訊息。

原文同步發表於個人部落格


一、 前提:

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

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

// 因為我的回傳錯誤訊息內容的型態是json,所以假使我接到資料是json格式,及代表我匯出發生問題勒
if (res.headers["content-type"].includes("application/json")){
   //如果有錯誤訊息
}
else{
   
}

三、再來錯誤訊息部分,由於我們接到的型態是{ responseType: 'blob' } 所以我們必須將blob轉回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);

四、最後,則是檔案匯出的檔名跟匯出方式

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();

五、完整程式碼如下

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);
        }
    });

參考資料:
Convert Blob to String in JavaScript

用Javascript替中文網址轉碼

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

Blob-MDN

使用axios如何下载文件


尚未有邦友留言

立即登入留言