一、背景介绍
Axios
是一个基于 Promise
的 HTTP
库,可以用在浏览器和 node.js
中。与传统的 Ajax
相比,Axios
的优势主要体现在: 支持 Promise API
、支持并发、支持请求与响应拦截、自动转换 JSON
数据、支持防御 XSRF
、符合 MVVM
设计理念。在目前大火的前端框架 Vue
中也内置了 Axios 框架
。
正是因为 Axios
的数据处理为 json
格式,所以只能获取文件流,但不能给与正确处理。具体表现为:
response.status
与 repsponse.headers
与期望相同,但 response.data
为一团乱码
- 浏览器没有自动下载文件
二、引入 Blob
容器实现文件下载
既然 Axios
无法正确处理文件流,便需要采用其他技术来达到预期效果。Blob
对象表示一个不可变、原始数据的类文件对象;从字面意思来看,Blob
也是一个可以存储二进制文件的容器。通过这项技术,可以完美地弥补 Axios
的不足。具体实现如下:
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 33 34 35 36 37 38 39
| export function download (param) { return axios({ url: '/web/bill/download', method: 'post', data: param, responseType: 'blob' }) }
download(this.param).then(response => { this.exeDownloadFile(response) })
exeDownloadFile (response) { let blob = new Blob([response.data], {type: response.headers['content-type']}) let fileName = response.headers['content-disposition'].match(/filename=(.*)/)[1] let href = window.URL.createObjectURL(blob) let downloadElement = document.createElement('a') downloadElement.style.display = 'none' downloadElement.href = href downloadElement.download = fileName document.body.appendChild(downloadElement) downloadElement.click() document.body.removeChild(downloadElement) window.URL.revokeObjectURL(href) }
|
虽然以上可以实现文件下载,但美中不足的是,当后台返回异常时,通过 Blob
对象依然可以下载到一个 undefined 文件。因此,在执行下载之前,需要对下载请求是否存在异常做出判断。具体实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| download(this.param).then(response => { let fr = new FileReader() fr.readAsText(response.data) fr.onload = function () { try { let jsonRet = JSON.parse(this.result) } catch (e) { this.exeDownloadFile(response) } } })
|