赞
踩
为什么要使用axios来下载文件?
这涉及到安全问题,我们平时下载文件,一般都是使用window.location.href来实现,即我们打开网站,只要输入对应的下载接口都可以实现下载。
例如:https://www.baidu.com?id=123,别人运用爬虫修改id的值,就可以获取到服务器的所有下载数据,因此我们需要加上一些权限校验
安全方式我们考虑了几种实现方式(总体来说权限校验的重点还是token)
这个就属于后端处理了,实现原理如下
后端把id+token+时间戳进行加密处理
=> 前端采用get请求(window.location.href)
=> 后端对id进行解密,校验时间戳/token/id三个参数
=> 回调
我们选择请求头带上token,代码如下:
axios({ method: 'get',// 设置请求方式 url: process.env.VUE_APP_CURRENTMODE + downloadUrl + record.id,// 设置请求地址 headers: {// 设置请求头 Authorization: this.$store.getters[`${this.accountType}AuthToken`] || this.$store.getters['baseAuthToken'] || 'xxxx' }, responseType: 'blob'// 设置相应数据的类型,设置后后台返回的数据会被强制转为blob类型;如果后台返回代表失败的data,前端也无法得知,依然会下载得到名为undefined的文件。 }).then(function (res) { let url = window.URL.createObjectURL(new Blob([res.data])) let link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', record.name)//设置下载文件名称,否则会得到undefined的文件 document.body.appendChild(link) console.log(res) link.click() link = null //销毁 })
当我们使用axios的时候,回调并不会自动下载
为什么axios没有办法实现下载功能?
因为浏览器的GET(frame、a)和POST(form)请求具有如下特点:
- response会交由浏览器处理
- response内容可以为二进制文件、字符串等
axios是请求具有如下特点:
- response会交由Javascript处理
- response内容仅可以为字符串 因此,axios本身无法触发浏览器的下载功能。
因此此处借助a标签来实现下载功能
还有更优美的写法,我们可以在axios成功回调中(也可以是axios拦截器,主要看如何封装请求的),判断返回的response如果是文件流,则我们可以创建a标签实现下载。
代码如下:
import axios from 'axios' const downloadBlob = (res,fileName) => { let url = window.URL.createObjectURL(new Blob([res.data])) let link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', fileName)//设置下载文件名称,否则会得到undefined的文件 document.body.appendChild(link) console.log(res) link.click() link = null //销毁 } const fetch = (apiName, data = {}, fetchConfigParams = {}) => { ... axios({ timeout: fetchConfig.timeout, url: _url, method: fetchConfig.method, headers, responseType: fetchConfig.responseType, crossDomain: true, xhrFields: { withCredentials: true }, data: { plain: data }, ...mockOptions }).then(res => { const authToken = res.headers.authorization if (res.status == config.successCode) { try { if (res.headers && (res.headers['content-type'] === 'application/x-msdownload' || res.headers['content-type'] === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')) { downloadBlob(res,data.fileName) res.data=''; res.headers['content-type'] = 'text/json' res.code = 200 resolve(res); } ... } ... }) } export default { fetch }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。