axios下載後臺傳過來的流檔案並設定下載檔名(如excel)
阿新 • • 發佈:2021-06-17
主要介紹兩種方法,使用Blob物件和 使用js-file-download
這兩種方法下載的檔案都不會亂碼,但是不管使用哪種方法,傳送請求時都要設定responseType
方法一:使用Blob物件
Blob物件表示一個不可變、原始資料的類檔案物件。Blob 表示的不一定是JavaScript原生格式的資料。File介面基於Blob,繼承了blob的功能並將其擴充套件使其支援使用者系統上的檔案。
一、Blob()
建構函式
摘自:Blob()
建構函式
語法
var aBlob = new Blob( array, options );
引數
- array是一個由
ArrayBuffer
,ArrayBufferView
Blob
,DOMString
等物件構成的Array
,或者其他類似物件的混合體,它將會被放進Blob
。DOMStrings會被編碼為UTF-8。 -
options是可選的,它可能會指定如下兩個屬性:
type
,預設值為""
,它代表了將會被放入到blob中的陣列內容的MIME型別。也就是設定檔案型別。endings
,預設值為"transparent"
,用於指定包含行結束符\n
的字串如何被寫入。 它是以下兩個值中的一個:"native"
,代表行結束符會被更改為適合宿主作業系統檔案系統的換行符,或者"transparent"
,代表會保持blob中儲存的結束符不變。
二、URL物件
通過建立URL物件指定檔案的下載連結。
// 建立新的URL表示指定的File物件或者Blob物件 const href = window.URL.createObjectURL(blob) window.URL.revokeObjectURL(href) // 釋放掉blob物件
在每次呼叫createObjectURL()方法時,都會建立一個新的 URL 物件,即使你已經用相同的物件作為引數建立過。當不再需要這些 URL 物件時,每個物件必須通過呼叫 URL.revokeObjectURL()方法來釋放。瀏覽器會在文件退出的時候自動釋放它們,但是為了獲得最佳效能和記憶體使用狀況,你應該在安全的時機主動釋放掉它們。
三、利用a標籤自定義檔名
const downloadElement = document.createElement('a') const href = window.URL.createObjectURL(blob) const contentDisposition = response.headers['content-disposition'] // 從response的headers中獲取filename, 後端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 設定的檔名; const patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*') const result = patt.exec(contentDisposition) const filename = decodeURI(escape(result[1])) // 處理檔名,解決中文亂碼問題 downloadElement.style.display = 'none' downloadElement.href = href downloadElement.download = filename // 下載後文件名 document.body.appendChild(downloadElement) downloadElement.click() // 點選下載 document.body.removeChild(downloadElement) // 下載完成移除元素
download 屬性設定檔名時,可以直接設定副檔名。如果沒有設定,則瀏覽器將自動檢測正確的副檔名並新增到檔案 。
四:主要完整程式碼
-
普通下載
axios.post(postUrl, params, { responseType: 'arraybuffer' }).then(response => { const fileType = [ 'application/vnd.ms-excel;charset=utf-8', // xls 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' // xlsx ] const blob = new Blob([response.data], { type: fileType }) const downloadElement = document.createElement('a') const href = window.URL.createObjectURL(blob) const contentDisposition = response.headers['content-disposition'] // 從response的headers中獲取filename, 後端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 設定的檔名; const patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*') const result = patt.exec(contentDisposition) const filename = decodeURI(escape(result[1])) // 處理檔名,解決中文亂碼問題 downloadElement.style.display = 'none' downloadElement.href = href downloadElement.download = filename // 下載後文件名 document.body.appendChild(downloadElement) downloadElement.click() // 點選下載 document.body.removeChild(downloadElement) // 下載完成移除元素 window.URL.revokeObjectURL(href) // 釋放掉blob物件 })
注:下載指定副檔名的檔案只需要對照MIME 參考手冊設定type即可。
方法二:使用js-file-download
-
安裝
npm install js-file-download --save
-
使用
import fileDownload from 'js-file-download' axios.post(postUrl, params, {responseType: 'arraybuffer'}).then(response => { const contentDisposition = response.headers['content-disposition'] // 從response的headers中獲取filename, 後端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 設定的檔名; const patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*') const result = patt.exec(contentDisposition) const filename = decodeURI(escape(result[1])) // 處理檔名,解決中文亂碼問題 fileDownload(response.data, filename) })