很多vue2项目可能都是根据这个模版来进行开发,在下载文件时可能会遇到一些问题导致下载不了,或者报错,因为这个框架在封装axios时,在响应拦截器中判断必须要返回值的,但是有个问题出现了,后台会直接把数据放在response.data中返回,并没有什么res.code、res.message之类的东西,因此我们需要新增改变一下拦截器中的东西。
在响应拦截器里,原本的写法就是这样的,让我们拿到返回值,来进行res.code等判断
service.interceptors.response.use(response => {
const res = response.data
...
})
现在我们在这个定义之下新增修改以下代码。
注:关于filename是后台传过来的名字,会直接放在response.headers中,如果没有可以自己设置或者和后台说一下给放上。
const isBlob = res instanceof Blob;
if (isBlob) {
// console.log('blob', res);
let blob = new Blob([res], { type: 'application/vnd.ms-excel;charset=utf-8' }) // 文件类型
let filename = window.decodeURI(response.headers['content-disposition'].split('=')[1])
let url = window.URL.createObjectURL(blob); // 创建下载链接
let aLink = document.createElement('a'); // 赋值给a标签的href属性
aLink.style.display = 'none';
aLink.href = url;
aLink.setAttribute('download', filename);
document.body.appendChild(aLink); // 将a标签挂载上去
aLink.click(); // a标签click事件
document.body.removeChild(aLink); // 移除a标签
window.URL.revokeObjectURL(url); // 销毁下载链接
} else {
if (res.code !== 20000 && res.code !== 200) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
}
这样就能把blob流文件进行下载了。
在api中的请求方法需要添加responseType类型
...
exportRecord(data) {
return request({
url: `/service/reportrecord/exportReportRecord/?${data}`,
method: 'get',
responseType: 'blob', //要添加这个
})
},
...
在methods里的方法(关于qs是啥可以百度一下,其实就是规范一下get请求格式,挺好用的)
async exportReportData() {
let data = this.$qs.stringify({
...
})
await this.$http.reportingRecords.exportRecord(data)
},
以下是完整的request.js响应拦截器内容
// 响应拦截器
service.interceptors.response.use(response => {
// 获取服务器响应的数据
const res = response.data
const isBlob = res instanceof Blob;
if (isBlob) {
// console.log('blob', res);
let blob = new Blob([res], { type: 'application/vnd.ms-excel;charset=utf-8' }) // 文件类型
let filename = window.decodeURI(response.headers['content-disposition'].split('=')[1])
let url = window.URL.createObjectURL(blob); // 创建下载链接
let aLink = document.createElement('a'); // 赋值给a标签的href属性
aLink.style.display = 'none';
aLink.href = url;
aLink.setAttribute('download', filename);
document.body.appendChild(aLink); // 将a标签挂载上去
aLink.click(); // a标签click事件
document.body.removeChild(aLink); // 移除a标签
window.URL.revokeObjectURL(url); // 销毁下载链接
} else {
if (res.code !== 20000 && res.code !== 200) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
}
}, error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
若是有更好的方法,请多多指教~