前提条件:本地启动项目测试时使用file-saver插件的saveAs(url,filename)方法下载从后台获取的文件地址,并自定义默认文件名,结果发现后缀为.zip的文件虽然自定义了filename,但是弹出下载弹窗时没有生效,依旧是取文件地址中的文件名
过程:先找原因,在下载的文件地址中,图片类的文件地址自定义文件名是生效的,只有.zip类型的文件地址没有生效,但理论上无论是图片类文件还是ZIP类文件,自定义文件名都应该能够生效。
查阅资料后,我认为可能的原因如下:
(1)虽然大多数现代浏览器都支持saveAs,但不同浏览器对文件下载的处理方式可能有所不同。某些浏览器可能在处理ZIP文件时存在特定的行为或限制。
(2)某些浏览器可能会根据HTTP响应头中的Content-Disposition字段来设置文件名,而不是完全依赖saveAs中指定的文件名。这可能导致在ZIP文件下载时,自定义文件名不生效。
浏览器的行为差异,我们没办法插手,而Content-Disposition字段是服务器配置的内容,前端也无法修改,所以只能另找其他方法
而,saveAs()方法中的url可接收blob、file、url三种形式,既然url试不通,也无法直接拿到file,那就让它变成blob试试
让url转成blob,可以使用axios的get请求,设置responseType为blob,获取返回数据,代码如下:
downloadFile(url, filename) {
axios
.get(url, { responseType: "blob" })
.then((res) => {
return res.data;
})
.then((blob) => {
saveAs(blob, filename);
})
.catch((err) => {
console.error("Error:", err);
});
},
结果一请求就出现了跨域的问题
那就只能上跨域的解决方法了,最常见的前端跨域解决方法就是代理
在vue.config.js配置如下(简单配置):
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
devServer:{
proxy:"http://112.xxx.xxx.xxx:xx/"//不好写全,总之就是把请求跨域的那个IP端口写上
}
})
然后需要替换文件地址中的ip端口为本地运行的ip端口,直接localhost:8080这样也行
最后实现能自定义文件名了
这个示例只是在本地运行的时候会报跨域错误,放上服务器可能就不会了
有个很搞笑的事情就是,我在做了跨域后直接使用saveAs()方法下载.zip的文件,结果它自定义文件名又生效了,没配置前就不生效,配置了之后就生效了,兜兜转转,感觉回到了起点。
不过还是要记录一下,或许saveAs在服务器上能顺利使用,而在本地运行的环境去下载服务器上的文件可能就有点小插曲,牢记教训就好。
坚持就是胜利!