下面需注意,ie保存blob对象与chrome firefox是有所不同的,需做一个判断。
import axios from 'axios'
import {Message} from 'element-ui'
// 文件下载,默认post请求.
export function downLoadFile (url, params = {}, fileName = '文件下载', callBack) {
axios.post(`${url}/`, params, {responseType: 'arraybuffer'}).then(res => {
if (res.headers['error-message']) {
// 截取响应头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进去火狐下载将无反应.
aTag.download = fileName
aTag.href = URL.createObjectURL(blob)
aTag.click()
document.body.removeChild(aTag)
URL.revokeObjectURL(aTag.href) // 释放blob对象
typeof callBack === 'function' ? callBack() : Message.success('下载成功')
}
})
}
做这个之前有个问题,后端返回数据转arraybuffer之后,如果抛出异常,就收不到具体的信息。
之前考虑有两种方案,一种前端直接写死,下载出错,但是肯定不合理的,这样抓不到具体的异常信息,第二种与后端约定一个映射表,前端做映射,这样也是比较死板的。
后面查阅一些资料决定,先与后端协商好,将错误信息放在响应头的一个字段里,请求来了先判断响应头,如果这个字段为null,则没有异常再往下执行拿到下载数据,如果异常字段有值则直接抛出异常信息并中断。