背景
最近工作上有个需求,是上传一个加密的文件到后端,后端解密后返回明文文件,踩了点坑,记录一下。
发送请求
首先是把密文上传到服务器,后端返回明文,此时需要我们请求增加一个配置,以 axios
为例,需要在 config
增加 responseType: 'blob'
,这样我们接收到的就是 Blob
类型的文件。
接收返回结果
上图就是 我们收到的返回结果,res.data
就是文件内容,可以看到是 Blob
类型的数据。
下载文件
得到结果后,需要把返回内容作为文件下载下来,尝试了两种方法:
1、使用 a 链接
const data = res.data; // Blob 文件
const blob = new Blob([data], { type: data.type });
// 得到一个以 blob 开头的下载链接
objectURL.value = window.URL.createObjectURL(blob);
// 文件名也是从响应头中得到
downloadName.value = window.decodeURIComponent(
res.headers["content-disposition"].split("=")[1]
);
然后这样下载
<a :href="objectURL" :download="downloadName">下载文件</a>
需要注意的是,使用 window.URL.createObjectURL
创建链接后,需要进行销毁操作是否内存,否则就是内容一样,也会重复创建
window.URL.revokeObjectURL(objectURL.value);
2、使用第三方库 file-saver
import { saveAs } from "file-saver";
const filename = window.decodeURIComponent(
res.headers["content-disposition"].split("=")[1]
);
saveAs(res.data, filename);
这样更简单,我最终使用第二种方案,倒不是因为技术上的复杂与否,是从产品角度考虑,服务端返回后应该立即下载文件,所以省去了点击按钮的那一步,也不想手动创建 dom,再模拟点击,就直接使用第三方库了。
3、还可以使用 File API 进行下载,这里就不多讲了,我也没试。。