Skip to content

使用 js 下载服务端传递的二进制文件

Posted on:2023年6月5日 at 09:50

背景

最近工作上有个需求,是上传一个加密的文件到后端,后端解密后返回明文文件,踩了点坑,记录一下。

发送请求

首先是把密文上传到服务器,后端返回明文,此时需要我们请求增加一个配置,以 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 进行下载,这里就不多讲了,我也没试。。