最近直接套了vue element admin上在写项目在下载文件时遇到了问题,现在记录下解决办法
由于使用了统一的接口设置,所有返回的数据都会在request.js中进行提前的过滤和筛选,所以需要前后端(都是我自己)一起协商解决这个问题
1,后台返回是设置自定义的headers,用来标记这是个文件,并且设置这个headers可见
response.setHeader("requestType","file"); // 自定义的header
response.setHeader("Access-Control-Expose-Headers", "requestType"); //设置这个header 可见
2,如果请求跨域了 ,转发时需要注意设置例如nginx 默认不会转发自定义的headers的 需要进行设置(我这里是在nginx中设置所有的headers)
add_header 'Access-Control-Allow-Headers' '*';
3,前端接收到请求以后需要先依据自定义的heade进行过滤,直接直接返回到相应的方法中进行处理例如在request.js中处理的部分添加判断:
if (response.headers.requesttype === 'file') {
return response;
}
4,到这里就已经获取到了数据流只需要网上的方法进行保存就行了
downloadFile(row) {
downloadFile(row.id)
.then(response=>{
console.info("文件下载")
var blob = new Blob([response.data], {
type: "application/file",
});
var url = window.URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = url;
a.download = row.fileName; // 文件名称需要自己定义。如果需要知道也可以在header中自定义一个文件名称返回 也可以随机生成一个 我这里是已经提前知道了文件名
a.click();
Message({
message: row.fileName+'已下载',
type: "success",
duration: 5 * 1000,
});
})
.catch((response) => {
Message({
message: response.msg,
type: "error",
duration: 5 * 1000,
});
});
},
我写这部分经历有些坎坷,开始查询页面如何进行文件存储,然后查询自定义header获取,然后查询nginx跨域headers的设置,然后查询自定义header为什么取不到
5、补充一下在请求的时候需要标记responseType
要不然返回的文件会不一致
export function downloadKeyFile(param) {
return request({
url: '/terminal/downloadKeyFile',
method: 'post',
data: param,
responseType: 'blob' // 表明返回服务器返回的数据类型
})
}