主要介紹兩種方法,使用 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
-
使用
