前端 從後端獲取(下載,導出)文件的方法

場景:

很多時候,前端存在需要從後端下載文件的情況,典型的就是導出excel表格。

一般存在兩種方式:

1,請求接口之後,直接打開請求該文件的地址,下載到本地。

2,請求接口之後,將獲取到的文件數據格式轉換之後,再下載到本地。

 

先說第一種:

很簡單,請求完接口之後,打開該文件的地址:

window.location.href = res.request.responseURL

responseURL這個地址其實和接口地址是一樣,直接打開它,就能默認下載到本地的下載路徑了。

非常方便,但是存在不足,比如不能修改文件的名稱。 

而且,有些場景使用這種方式是行不通的,比如,很多管理系統,都是需要登錄的,既然要登錄,那就一般都會需要驗證每個請求是否安全,往往需要在header裏帶上token,後端纔會給你這個請求放行。

所以,這種方式,你請求接口之後,轉到這個鏈接,其實就是再請求了一次,這個時候你是不好在請求裏帶上token的,自然也就拿不到你要的文件。

所以,這個時候就要用第二種方式。

第二種方式:

第二種方式,就是正常的api請求,獲取到文件數據之後,在本地模擬一次點擊按鈕下載,不過這次下載不是再向後端請求一次api,而是把第一次請求api之後,後端返回的文件數據轉換成合適的格式之後下載下來。

exportFile(this.queryParam).then(res => {
        if (res.status === 200) {
          const xlsx = 'application/vnd.ms-excel'
          const blob = new Blob([res.data], { type: xlsx })
          const a = document.createElement('a') // 轉換完成,創建一個a標籤用於下載
          // const name = res.headers['content-disposition']
          // a.download = name.split('=')[1]
          a.download = `${this.$t('menu.operatelog')}.xlsx`
          a.href = window.URL.createObjectURL(blob)
          a.click()
          a.remove()
          document.body.removeChild(a) //也可以這麼移除
          // 直接打開下載文件的鏈接
          // window.location.href = res.request.responseURL
        }
      })

代碼很容易看懂,這裏就不解釋了,說幾個需要提醒的地方。

1.不管是第一種方式還是第二種方式,儘量讓後端指定好文件的類型。當然,使用第二種方式,前端可以再次指定好文件類型。

2.這裏將獲取到的文件內容轉換成blob類型的數據,是最常見的下載文件數據的格式,當然還可以使用別的方式。

3.這裏創建a標籤取下載文件,還可以用別的方式,或者如果碰到瀏覽器兼容性的問題,可能需要個性化處理。

4.download這裏可以拿後端返回的文件名,也可以自己定義文件名,看你自己哪個方便一些。如果後端拿到的文件名是亂碼,建議直接在前端定義文件名。

5.最關鍵的是,下載文件亂碼的問題,很多人碰到,解決方法也很簡單。

export function exportFile (parameter) {
  return axios({
    url: `${api.file}/export`,
    method: 'get',
    data: parameter,
    header: {
      headers: { 'Content-Type': 'application/x-download' }
    },
    responseType: 'blob'
  })
}

在請求接口的header裏一定要指定responseType爲blob,否則把返回的文件數據轉換成blob對象,blob是不認識的,就會出現亂碼。

 

歡飲補充。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章