利用Blob类文件对象进行有权限校验的文件下载

不用<a>标签怎么实现下载功能呢?

我们知道,一般情况下,前端要去请求下载一个文件,一般是直接把地址写在<a>标签里面,可是如果我想在发送请求的时候就直接携带 tokne 校验身份呢?

本文就来介绍一种利用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
26
27
28
29
30
31
32
import { saveAs } from 'file-saver';
import axios from 'axios';
const App = () => {
const download = (e) => {
axios({
method: 'get',
url: `#`,
headers: {
Authorization: yourtoken,
},
responseType: 'arraybuffer',
})
.then((response) => {
const blob = new Blob([response.data], {
type: 'application/zip;charset=utf-8',
});
const header = response.headers['content-disposition'];
const fileNameBeforeDecode = header.substring(header.indexOf('=') + 1);
const fileName = decodeURI(fileNameBeforeDecode);
saveAs(blob, fileName);
})
.catch((e) => {
// Handle error
});
};
return (
<div>
<span onClick={download}>下载</span>
</div>
);
};
export default App;

首先要引入需要的file-saver和 axios,headers里面携带权限 token,此外还需要添加一个很关键的属性:responseType: 'arraybuffer',

responseType可以告诉服务器你期望的响应类型,默认值为空,期望的数据类型是DOMString,如果更改为arraybuffer,则期望的数据类型变为ArrayBuffer对象

拿到返回的响应数据,将其封装为Blob 对象,本例中文件类型是 zip 文件,记得要把数据转成utf-8格式。

根据上图的响应内容(我就不打码了),把需要的文件名通过提取response.headers['content-disposition'](有连字符的属性要用[]来读)头部信息,然后截取字符串再转码,就获得了想要的文件名。

最后用代码开头安装的file-saver将文件存起来,此时的效果就是一个文件下载的弹窗,和<a>标签的效果一样,但是却完成了权限的校验。

要实现本文开头的需求,还可以用 《React 多个系统之间登录登出逻辑的实现》一文提到的 把 token 加密追加到 url 里面的写法,有兴趣的可以查看文章了解。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2018-2020 Jee
  • Visitors: | Views:

如果您觉得此文章帮助到了您,请作者喝杯咖啡吧~

支付宝
微信