下面需注意,ie保存blob對(duì)象與chrome firefox是有所不同的,需做一個(gè)判斷。
import axios from 'axios'
import {Message} from 'element-ui'
// 文件下載,默認(rèn)post請(qǐng)求.
export function downLoadFile (url, params = {}, fileName = '文件下載', callBack) {
axios.post(`${url}/`, params, {responseType: 'arraybuffer'}).then(res => {
if (res.headers['error-message']) {
// 截取響應(yīng)頭error-message拋出異常信息
const message = decodeURI(res.headers['error-message']) // 解決中文亂碼問題,需后端編碼配合。
Message.error(message)
return false
}
const blob = new Blob([res.data], {type: ''})
if (window.navigator.msSaveOrOpenBlob) {
// 兼容IE10及以上
navigator.msSaveBlob(blob, fileName)
} else {
// chrome/firefox
let aTag = document.createElement('a')
document.body.appendChild(aTag) // 如果不append進(jìn)去火狐下載將無反應(yīng).
aTag.download = fileName
aTag.href = URL.createObjectURL(blob)
aTag.click()
document.body.removeChild(aTag)
URL.revokeObjectURL(aTag.href) // 釋放blob對(duì)象
typeof callBack === 'function' ? callBack() : Message.success('下載成功')
}
})
}
做這個(gè)之前有個(gè)問題,后端返回?cái)?shù)據(jù)轉(zhuǎn)arraybuffer之后,如果拋出異常,就收不到具體的信息。
之前考慮有兩種方案,一種前端直接寫死,下載出錯(cuò),但是肯定不合理的,這樣抓不到具體的異常信息,第二種與后端約定一個(gè)映射表,前端做映射,這樣也是比較死板的。
后面查閱一些資料決定,先與后端協(xié)商好,將錯(cuò)誤信息放在響應(yīng)頭的一個(gè)字段里,請(qǐng)求來了先判斷響應(yīng)頭,如果這個(gè)字段為null,則沒有異常再往下執(zhí)行拿到下載數(shù)據(jù),如果異常字段有值則直接拋出異常信息并中斷。