在很多情况下,我们需要通过后端提供的接口来获取动态生成的文件,而我们请求接口的时候,往往后端返回的是二进制数据流。这时我们该如何将后端返回的二进制数据流转换为我们需要的文件呢?接下来我将以我们常用的axios请求为例来演示。

  1. 在发送请求的时候我们需要将请求配置项中的responseType设置为blob或者arraybuffer,意思是识别响应类型为二进制数据流。
1
2
3
4
5
6
7
axios({
method:"get", // 或post
url: '接口地址',
responseType:'blob' // 或者'arraybuffer',这一设置是关键
}).then(res => {
...
})
  1. 获取响应结果后,将其转化为Blob对象,并生成文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
axios({
method: "get",
url: 接口地址 + "?data=" + encodeURI(JSON.stringify(this.value)),
responseType: "blob"
}).then(res => {
//这里res.data是返回的blob对象
const blob = new Blob([res.data], {
type: 'application/octet-stream;charset=utf-8' // 通用的二进制流类型
// 在type里还可以用 charset设置文件流的编码类型,默认为utf-8
});
// 从response的headers中获取filename, 后端设置的文件名
const contentDisposition = res.headers["content-disposition"];
const patt = new RegExp("filename=([^;]+\\.[^\\.;]+);*");
let result = patt.exec(contentDisposition);
let filename = result[1];
let link = document.createElement("a");
let href = window.URL.createObjectURL(blob); //创建下载的链接
link.style.display = "none";
link.href = href;
link.download = filename; // 设置下载的文件名
document.body.appendChild(link);
link.click(); // 点击下载
document.body.removeChild(link); // 下载完成移除元素
window.URL.revokeObjectURL(href); // 记得释放掉blob对象,不然会占用内存
});