Emberjs 經過 axios 下載文件

Emberjs 經過 axios 下載文件

摘要: 目前項目中須要與後端合做,經過發送 GET 請求,後端返回文件流,前端進行文件的下載。

使用到的技術有:javascript

  • Emberjs
  • axios

思路

接到這個需求的話,想着使用建立 a 連接,而後模擬點擊 a 連接來完成下載,可是狀況不是這樣的。後端有多於一個的下載接口,首先是生成下載文件的接口, 這個接口主要是返回 須要下載的文件的name 以及相應的接口地址。而下載的文件可能不止一個,同時,對文件接口地址發送 GET 請求,會返回文件流,可是咱們須要的是 CSV 格式的文件,因此想到經過 axios 來實現這個需求。前端

具體作法

既然方向肯定了,那就是去作了。java

在項目中安裝插件/導入 axios

如今 Emberjs 封裝好的 axios 插件 - ember-axios ,使用 ember install axios。這個插件沒有文檔,因此只能看源碼,還好源碼比較簡單,就是簡單的將 axios 的一些方法封裝成一個 service 內的方法。ios

在項目文件中引入 axios

安裝後在 Emberjs 項目中將此 service 引入近來git

import { inject as service } from '@ember/service';

export default Controller.extend({
    // ...
    axios: service()
    // ...
});

這樣便可使用這個插件中封裝的一些 axios 的方法。github

使用

以前也說過當前項目須要先發送一個請求,請求文件的接口地址。返回的值的格式爲:axios

{
    "fileNames":[
        "filename=downloadFile1.csv",
        "filename=downloadFile2.csv"
    ],
    "status":"ok"
}

能夠看到,如咱們所想的那樣,返回的並不必定是單個文件的地址,因此咱們在接收到這個數據後:後端

import { isEmpty } from '@ember/utils';
import { all, reject } from 'rsvp';

//...
.then(data=> {
    if (data.status !== 'ok' || isEmpty(data.fileNames)) {
        return reject();
    }

    return all(data.fileNames.map(ele => {
        return axios.axios({
            url: `${ele}`,
            method: 'get',
            responseType: 'blob'
        });
    }));
});

在等待上面的請求發送成功以後,咱們看看這段代碼的意思。最上面的兩個 import 是引入的一些 Emberjs 中封裝的一些通用方法以及 promies 方法.在 then 以內的代碼,先是驗證是否返回成功。而後對數據進行遍歷,併發送 axios 封裝的 get請求。 其中axios.axios()ember-axios 封裝的axios.create(this.config()) 源碼地址 ,同時注意的是 config 對象中 responseType 填寫的是 blob,這是保證文件可以下載成功的基礎。
請求發送成功以後,咱們須要對返回的數據進行處理,也就是:瀏覽器

.then(data => {
    data.forEach((res, index) => {
        const content = res.data,
            blob = new Blob([content], { type: 'text/csv' }),
            fileName = fileNames[index];

        if ('download' in document.createElement('a')) { // 非IE下載
            const elink = document.createElement('a');

            elink.download = fileName;
            elink.style.display = 'none';
            elink.href = URL.createObjectURL(blob);
            document.body.appendChild(elink);
            elink.click();
            URL.revokeObjectURL(elink.href); // 釋放URL 對象
            document.body.removeChild(elink);
        } else { // IE10+下載
            navigator.msSaveBlob(blob, fileName);
        }
    });
}).catch(() => {
});

這段代碼須要注意的是咱們new Blob()接收的是 res.data 這個須要特別注意。另外就是此方法的第二個參數接收的 {type: 'text/csv'},由於次項目下載的是csv文件格式,其餘的能夠參考 MIME. 其餘的就是建立一個 display:nonea標籤,並觸發點擊事件。這時候瀏覽器就會進行下載。併發

總結

這算是在 Embjerjs 中進行下載流文件的一次船新嘗試。

Write By Frank Wang
相關文章
相關標籤/搜索