在开发过程中前端如何与后端配合实现文件下载至本地?特殊格式文件如何处理?
概要
需求:实现二进制下载、URL下载、跨域下载
后端:Spring
前端:Vue
要点:后端返回文件流还是URL下载地址?
一、二进制式下载
- 流程:后端返回二进制文件流的情况下,前端需要使用JS对象Blob构造函数来接收并储存文件流,当服务器端发送完文件流之后,前端使用a标签HTML5新属性download属性实现本地储存,以达到实现下载需求。
- 后端返回内容:二进制文件流
- 前端做处理:正常请求,后端给我们返回的是二进制流文件,由于前端需要使用Blob接受,所以在请求头中需要告知服务器需要返回的数据类型,即 responseType: “blob”,服务器返回的即是个blob对象。
- 思路:拿到Blob对象之后,使用URL.createObjectURL (前端API)生成一个可使用的URL地址,之后把这个URL地址赋给一个临时创建的a标签,当然我们的a标签也需要download属性才可以拥有下载属性
- 前端代码:
this.$axios({
method: "post", //请求方式
responseType: "blob", //告诉服务器我们需要的响应格式
url: "fileService/fileService/download", //地址
data: {
fileId: item.fileId,
authorId: window.localStorage.getItem("authorId")
}
}).then(res => {
let url = window.URL.createObjectURL(new Blob([res.data])); //转换为可用URl地址
let link = document.createElement("a"); //创建a标签
link.style.display = "none"; //使之不可见
link.href = url; //赋URL地址
link.setAttribute("download", item.fileName); //设置下载属性、以及文件名
document.body.appendChild(link); //将a标签插至页面中
link.click(); //强制触发a标签事件
});
- 优点:适合1M以内的小文件下载
- 缺点:文件会在服务器端完全发送完毕之后、才会展示出下载提示,用户体验感极差。
二、解析:URL下载
- 流程:后端返回URL下载路径,前端直接放置a标签,并赋予a标签download属性,使其下载而不是直接打开。
- 后端返回内容:文件第三方下载地址
- 前端做处理:前端创建a标签,赋予href为文件下载地址即可
- 前端代码:
Download() {
let link = document.createElement("a"); //创建a标签
link.style.display = "none"; //使其隐藏
link.href = this.Data.filePath; //赋予文件下载地址
link.setAttribute("download", this.Data.fileName); //设置下载属性 以及文件名
document.body.appendChild(link); //a标签插至页面中
link.click(); //强制触发a标签事件
},
- 优点:不限制文件大小
- 缺点:目测 无!
三、解析:跨域下载
- 表现:继 ‘二’ 所述,在URL下载方式中,遇到mp4 / jpg / png等浏览器可以识别的文件格式时,下载提示框未弹出,直接在浏览器打开了该文件。
- 原因:经观察是a标签的download属性失效。查阅一些资料后发现download属性也受同源策略的影响,即非同一端口下不能直接下载第三方文件,所以这里download失效之后做的仅仅是跳转功能,类似于某一视频下载地址直接通过浏览器get访问跳转。
- 解决方式:后端 oss可以批量设置HTTP头,设置HTTP请求头为Content-Disposition 为 attachment即可,访问的时候就是直接下载而不是浏览!
版权声明:本文为CSDN博主「米斯特曹、」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:前端:下载文件实现方式及跨域下载(详解)