一、自定义下载文件名称
1、封装下载方法(可以通过挂载在vue实例上成为全局函数)
import requset from 'axios'
// 经过请求拦截器、响应拦截器处理
onloadFileName(url,method,params,fileName){
request({
url:url,
method:method,
// get 方法传参为例
data:{
...params
},
// 添加响应数据类型
responseType: 'blob',
// 添加文件下载特定请求头
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
}).then(res =>{
// res 为响应拦截器返回的内容,大家可以对比自己的响应拦截器修改下面方法的判断
if (!data) {
this.$message.warning("文件下载失败");
return;
}
// web Api种操作流文件的方法
if (typeof window.navigator.msSaveBlob !== "undefined") {
// msSaveBlob:只提供一个保存按钮
// window.navigator.msSaveBlob(new Blob([data]),`${fileName}.txt`);
// msSaveOrOpenBlob:提供保存和打开按钮
//window.navigator.msSaveOrOpenBlob(newBlob([data]),`${fileName}.txt`);
window.navigator.msSaveBlob(
new Blob([data]),
filename + ".xls"
);
} else {
// 自定义实现流文件下载
let url = window.URL.createObjectURL(new Blob([data]));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", fileName + ".xls");
document.body.appendChild(link);
link.click();
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
})
}
2、调用下载方法
this.onloadFileName('xxx/xxx/xx','get',{id:'xxxxxxx'},'文件一')
二、文件名称从后端响应头数据中获取
·1、处理响应拦截器返回的数据,将文件名暴露暴露出去
// 设置请求接受拦截器 响应拦截器中兼容处理流数据
serves.interceptors.response.use(response => {
// 设置接受数据之后,做什么处理
const res = response.data
if (!res.code && res.code === 200) {
// 数据是流
if(response.headers['content-disposition']){
return {
blobData:res,
contentDisposition:response.headers['content-disposition']
}
}
// 正常情况下
else{
return res
}
}
})
2、封装下载方法
onloadFileName(url,method,params){
request({
url:url,
method:method,
// get 方法传参为例
data:{
...params
},
// 添加响应数据类型
responseType: 'blob',
// 添加文件下载特定请求头
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
}).then(res =>{
if (!res.blobData) {
this.$message.warning("文件下载失败");
return;
}
// web Api种操作流文件的方法
if (typeof window.navigator.msSaveBlob !== "undefined") {
// msSaveBlob:只提供一个保存按钮
// window.navigator.msSaveBlob(new Blob([data]),`${fileName}.txt`);
// msSaveOrOpenBlob:提供保存和打开按钮
//window.navigator.msSaveOrOpenBlob(newBlob([data]),`${fileName}.txt`);
window.navigator.msSaveBlob(
new Blob([res.blobData]),
res.contentDisposition+ ".xls"
);
} else {
let url = window.URL.createObjectURL(new Blob([res.blobData],
{
type:
".xlsx"
}
));
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
// decodeURIComponent()解码文件名称
// data.contentDisposition.split('=')[1] 分割文件名称
const fileName = decodeURIComponent(data.contentDisposition.split('=')[1])
link.setAttribute("download",fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
}
3、调用下载方法
this.onloadFileName('xxx/xxx/xx','get',{id:'xxxxxxx'})
问题一:后端返回的数据无法解析
在请求函数中添加响应类型以及响应头
问题二、后端返回的文件名经过相应拦截器后无法暴露出来导致无法获取文件名报错。
后端返回二进制流数据时设置请求头,添加可暴露出的字段
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition")
response.setHeader("Content-Disposition", ...)