JS下載文件兩種方式總結(jié):
下載文件主要分為兩種形式惧互,具體使用哪種方式取決于后臺碱呼;
1.如果后臺服務(wù)器的靜態(tài)目錄有可供下載的靜態(tài)資源忽你,后臺接口返回文件路徑仪或,直接window.location.href=url或者window.open(url)或者創(chuàng)建a標(biāo)簽并指定a.href=url模擬點擊進(jìn)行下載即可确镊;
2.如果后臺服務(wù)器無可供下載的靜態(tài)資源,返回的是一個文件流(response-type: application/octet-stream;charset=UTF-8 )范删,則使用第二種方式(將文件寫入內(nèi)存蕾域,并且創(chuàng)建a元素,a鏈接href屬性指向內(nèi)存中的文件到旦,download屬性指向要下載的文件名旨巷,模擬a元素的點擊事件進(jìn)行下載然后移除a元素)。
本文主要說明采用文件流的方式下載文件添忘。
一采呐、后臺服務(wù)器有靜態(tài)資源且是固定的文件名(GET方式下載文件)
window.location.href="http://www.域名/template.xlsx(請求返回的url地址)"
二、后臺返回文件流
方案1:采用FileReader讀取二進(jìn)制流昔汉,下載讀取后的結(jié)果
import axios from 'axios'
axios.post(this.$globalConf.atapPathPrefix + '/system/indicator/export', postParams, { responseType: 'blob' }).then(res => {
let blob = res.data;
let reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function(e) {
let a = document.createElement('a');
let fileName = res.headers["content-disposition"] ? res.headers["content-disposition"].split(';')[1].split('=')[1] : new Date().getTime() + '.xlsx'
a.download = decodeURIComponent(fileName)//解碼
a.href = e.target.result;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
})
方案二:通過URL.createObjectURL讀取二進(jìn)制流并返回一個對象URL懈万,原理同上
import axios from 'axios'
axios.post(this.$globalConf.atapPathPrefix + '/system/indicator/export', postParams, { responseType: 'blob' }).then(res => {
//這里res.data是返回的blob對象,即對應(yīng)的二進(jìn)制流
let blob = res.data
let downloadElement = document.createElement('a');
let href = window.URL.createObjectURL(blob); //創(chuàng)建下載的鏈接
let fileName = res.headers["content-disposition"] ? res.headers["content-disposition"].split(';')[1].split('=')[1] : new Date().getTime() + '.xlsx'
downloadElement.href = href;
downloadElement.download = decodeURIComponent(fileName)//解碼
document.body.appendChild(downloadElement);
downloadElement.click();
document.body.removeChild(downloadElement);
window.URL.revokeObjectURL(href); //釋放掉blob對象
})
可能出現(xiàn)的問題:
無法獲取headers的content-disposition字段
本次請求獲取到fileName如下:
image.png
解決辦法
在服務(wù)端設(shè)置header
Access-Control-Expose-Headers: Content-Disposition
(3)Access-Control-Expose-Headers
該字段可選。CORS請求時靶病,XMLHttpRequest對象的getResponseHeader()方法只能拿到6個基本字段:Cache-Control会通、Content-Language、Content-Type娄周、Expires涕侈、Last-Modified、Pragma煤辨。如果想拿到其他字段裳涛,就必須在Access-Control-Expose-Headers里面指定木张。