原来遇到的下载文件基本都是通过文件的url进行下载,但是最近遇到了一个通过ajax请求下载excel的需求,这次特地记录一下,以免以后踩坑。
通过ajax请求后接口data数据为这种格式,应该是一个文件流,是一个乱码,不过这个不需要看得懂。
对于这类接口的请求,headers中的Content-Type不需要特别去设置,只需根据后端配置为表单或者json即可。
因为请求得到的是文件的二进制数据,那么首先肯定是要在浏览器中保存二进制数据,在js中保存二进制数据需要用的Blob类型的对象,再通过浏览器将这个文件下载至本地,下面是代码1
2
3
4
5
6
7
8
9const blob = new Blob([data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'})
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob)
downloadElement.href = href
downloadElement.download = 'xxx.xlsx'
document.body.appendChild(downloadElement)
downloadElement.click()
document.body.removeChild(downloadElement) // 下载完成移除元素
window.URL.revokeObjectURL(href) // 释放掉blob对象
这里有几点需要注意下:
1、需要设置Blob对象的type,我这里下载的是excel文件,也可以换成其他文件,不过type就需要更换。
2、对于下载创建的标签要记得在下载之后移除。
到这里其实还没有结束,有一个关键的步骤,需要在ajax请求中设置responseType: ‘blob’,这样才能保证获取到的二进制数据正确,开始的时候没注意到这个,文件虽能下载,但是打开都是损坏的。
axios可以通过创建实例的方法指定responseType
1
2
3
4
5
6var instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
responseType: 'blob'
});XMLHttpRequest提供了相关设置的api
1
2let xhr = new XMLHttpRequest()
xhr.responseType = 'blob'这里比较费劲的就是jquery的$.ajax,jquery中ajax的datatype并没有blob,目前还未找出来比较好的解决方法,建议可以自己封装XMLHttpRequest来下载二进制文件。