vue项目,有两种方式实现请求接口返回文件流并进行下载:
第一种:使用a标签的特性,使用链接实现
第二种:下载文件流的方式
下载
这里使用的是前后端合作的方式
下载动态文件流就是文件存储在后台,需要使用接口请求,来实现文件的下载
const URL_GLOBAL = {
development: "http://localhost",
production: "https://baidu.com",
developmentPort: ":8888/hhh",
productionPort: "/abc",
}
this.globalURL = URL_GLOBAL[process.env.NODE_ENV] + URL_GLOBAL[process.env.NODE_ENV + 'Port'];
Download Excel
const URL_GLOBAL = {
development: "http://localhost",
production: "https://baidu.com",
developmentPort: ":8888/hhh",
productionPort: "/abc",
}
this.globalURL = URL_GLOBAL[process.env.NODE_ENV] + URL_GLOBAL[process.env.NODE_ENV + 'Port'];
Download Excel
import axios from "axios";
注意必坑:
当获取后端设置的响应头字段时,比如设置的文件名称或者自定义的参数时,
要在后端设置响应头,必须要设置以下代码,来公开自定义响应头,否则前端拿不到响应头中对应的数据:
response.setHeader("Access-Control-Expose-Headers","content-disposition");
exportExcel() {
let params = {
type: 'code'
}
//下载文件流
let url = this.globalURL + '/code/getcode'
axios.post(url,params,{
responseType:'blob'
}).then(res => {
const name = res.headers['content-disposition'];
let fileName = '';
if (name) {
const str1 = name.replace(' ', '');
const arr1 = str1.split(';');
arr1.some(item => {
if (item.indexOf('filename') != -1) {
fileName = item.split('=')[1];
}
return item.indexOf('filename') != -1;
});
if (fileName === ''){
fileName = 'excel.xlsx'
}
} else {
fileName = 'excel.xlsx'
}
try {
let objectUrl1 = window.URL.createObjectURL(new Blob([res.data]));
let elink = document.createElement('a');
elink.setAttribute('download', decodeURI(decodeURI(fileName)));
elink.style.display = 'none';
elink.href = objectUrl1;
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
window.URL.revokeObjectURL(elink.href);
}catch (err){
this.$message.warning('download error!')
}
})
},
这种方式,不管接口是get请求,还是post请求都可以用
const service = axios.create({
baseURL: URL_GLOBAL[process.env.NODE_ENV] + URL_GLOBAL[process.env.NODE_ENV +'Port'],
timeout: 300000,
});
配置请求头,将需要的信息存储在请求头中
service.interceptors.request.use(
async (config)=>{
if (process.env.NODE_ENV !== 'development'){
config.headers['username'] = 'annie'
}
return config
},
error => {
Promise.reject(error)
}
)
import fetch from "../request"
使用按钮触发下载事件
Download excel
注意必坑:
当获取后端设置的响应头字段时,比如设置的文件名称或者自定义的参数时,
要在后端设置响应头,必须要设置以下代码,来公开自定义响应头,否则前端拿不到响应头中对应的数据:
response.setHeader("Access-Control-Expose-Headers","fileName");
详细了解Access-Control-Expose-Headers:Access-Control-Expose-Headers 响应报头、跨域 公开响应头_withexposedheaders-CSDN博客
接口请求
downloadFiles() {
return new Promise((resolve, reject) => {
fetch({
url: "/down/download",
method: "get",
params: {
id: '222',
},
responseType: "blob",
})
.then((res) => {
// 获取后端设置的响应头字段时,比如设置的文件名称或者自定义的参数时,
// 在后端设置响应头时,必须要设置以下代码,来公开自定义响应头,否则前端拿不到:
// response.setHeader("Access-Control-Expose-Headers","fileName");
const fileName = res.headers["filename"];
const blob1 = res.data;
console.log(blob1)
console.log(fileName)
if ("download" in document.createElement("a")) {
const elink = document.createElement("a");
elink.download = decodeURIComponent(fileName);
elink.style.display = "none";
elink.href = URL.createObjectURL(blob1);
document.body.appendChild(elink);
elink.click();
console.log(elink)
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
} else {
// IE10+下载
navigator.msSaveBlob(blob1, fileName);
}
})
.catch((err) => {
reject(err);
});
});
},