文件下载
文件下载方式
前端涉及到的文件下载还是很多应用场景的,那么前端文件下载有多少种方式呢?每种方式有什么优缺点呢?下面就来一一介绍。
a标签
定义与用法
- 首先实现
download功能,条件必须满足:所要下载的文件与js或当前页面同源。即window.location.protocol(传输协议)+window.location.host(域名)必须有,且一致; - 如果是本地文件,请启动本地服务,使用
localhost访问页面; - 通过
a标签的download属性来实现文件下载;download为h5中新增的a标签属性;download+href使a标签具备点击下载功能; download属性也可以设置一个值来规定下载文件的名称;若没有设置拓展名,浏览器将自动检测正确的拓展名(.img,.png、.pdf);
兼容性测试及结果
- 代码
1 | <a href="./imgs/cs.jpg">同源图片,不带download</a> |
1 | function down(url) { |
- pc端浏览器兼容性

总结
- html不支持的文件,无论同源还是不同源,有没有download属性,都会下载。
- html支持的文件,同源且有download属性,除ie外都会下载。
- html支持的文件,不同源,无论有无download属性,都不会下载,浏览器会直接跳转打开。
Blob对象
场景:后端返回给前端
文件流,前端通过Blob下载;文件流格式如下:

Blob对象
下面是blob对象的定义,来自MDN:
Blob对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成ReadableStream来用于数据操作。
Blob表示的不一定是JavaScript原生格式的数据。File接口基于Blob,继承了blob的功能并将其扩展以支持用户系统上的文件。
blob对象是html5新增的对象,它的作用是用来存储二进制数据的,比如图片、视频、音频等,它的使用方法如下:
1 | /** |
这里主要关注的是type属性,默认情况下,blob对象是没有type属性的,那么这个Blob就是一个无类型的Blob,文件不会损毁,但是无法被正常识别。
URL.createObjectURL
下面是blob对象的定义,来自MDN:
URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的 URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的 URL 对象表示指定的 File 对象或 Blob 对象。
这个方法是用来创建一个url的,它的作用是把一个blob对象转换成一个url,这个url可以用来下载文件,也可以用来预览文件,代码如下:
1 | const url = URL.createObjectURL(blob) |
这里需要注意的是,这个url的生命周期和创建它的窗口中的document绑定,也就是说,当我们的document被销毁后,这个url就会失效,会自动释放它们,但是为了获得最佳性能和内存使用状况,我们应该在安全的时机主动释放掉它们,代码如下:
1 | URL.revokeObjectURL(url) |
下载文件流
指定返回数据格式
首先指定返回数据格式为blob:
responseType: 'blob'
1 | // 导出报表 |
响应头headers获取文件信息
在响应数据
response.headers["content-disposition"]中获取文件信息;包含文件名和文件类型;如下图所示:

可以在响应拦截器里面做数据处理:
- 中文转码了,转回去;
- 将文件信息存到缓存,调用下载接口的时候获取文件信息;(给a标签的download设置文件名)
1 | //接收到响应数据并成功后的一些共有的处理 |
调用下载接口
- 我们可以打印一下res,是一个Blob对象;(如果接口没有设置responseType: ‘blob’,这里是后端返回的文件流)
1 | getMeetRoomExport(this.exportParams).then((res) => { |

- 接口请求
这里和后端商量是
docx类型的文件,所以type值如下所示,其他类型的type值设置可参考MDN;
1 | getMeetRoomExport(this.exportParams).then((res) => { |
至此,文件就会下载成功;
IE兼容
IE浏览器是不支持download属性的,Internet Explorer 10的 msSaveBlob 和 msSaveOrOpenBlob 方法允许用户在客户端上保存文件。
用法:
- msSaveBlob:只提供一个保存按钮
1 | window.navigator.msSaveBlob(blobObject, [name]); |
- msSaveOrOpenBlob:提供保存和打开按钮
1 | window.navigator.msSaveOrOpenBlob(blobObject, [name]); |
- 兼容IE的下载
1 | getMeetRoomExport(this.exportParams).then((res) => { |
下载拓展
回到我们刚才下载的问题,我们是通过
blob对象来解决,但是我们的type属性是写死的,如果在文件类型是确定的情况下是没问题的,但是如果这个接口就是下载文件的接口,文件可能是各种类型的,我们应该怎么处理?
- 和接口提供者进行协商,确定下载的文件的格式,然后前端将
type写死; - 通过枚举和响应头
response.headers["content-disposition"]来实现;
枚举方式
- 新建config 写入blobType的对象
1 | export const blobType = { |
- 引入,通过缓存中的文件名后缀确定type值;大致思路如下:
1 | // 1.引入枚举 |
Blob拓展
不仅是后端传来的文件流可以下载,字符串、对象、数组等任意类型都可以下载;
1 | // 下载txt格式的文件; |
现象:点击按钮,下载名为 fsl.txt文件,内容为 “使用Blob对象下载文件”;
URL.createObjectURL拓展
使用URL.createObjectURL实现图片本地预览
这个方法是用来创建一个url的,它的作用是把一个blob对象转换成一个url,这个url可以用来下载文件,也可以用来预览文件;
1 | <body> |