场景
- 已知一个文件的存储链接,有下载操作,用户可以下载该文件,但是如果简单地通过
window.location.href = file.path
来实现的话,结果是web跳转到一个预览该文件的新页面,而且还需要手动点下载文件才能真正下载到本地。 - 同理,a标签的href改成file.path也是同样的结果。
问题
- 现在希望用户不用预览文件,而是在第一次下载操作之后就直接把文件下载到本地。
实现
- 用XMLHttpRequest直接请求file.path,然后设置
responseType
能够控制请求返回的数据类型,默认是text类型,设置成blob型就能下载文件,还有arraybuffer, json等类型,什么场景用什么类型,具体情况具体分析,比如我只是想拿到文件文本内容做展示,那就直接text类型,比如我有一堆文件需要打包到zip里一起给到用户,那就用arraybuffer类型...... 所有类型见 - 这里直接用axios封装就好了
import axios from 'axios' export function getFile (path, type = 'text') { // path = '把路径前缀改成配置的proxy前缀,本地需要代理' // 本地把前缀换成代理前缀 // 生产环境则是原path,但是需要后台配置跨域 return new Promise((resolve, reject) => { axios.get(path, { responseType: type }).then((res) => { resolve(res.data) // 这里的res.data就是我们需要的文件对应responseType类型的数据了 }).catch(err => { reject(err) }) }) }
- 然后就能异步处理自己的逻辑了,这里只举下载文件的例子,具体情况具体分析
// vue methods dwonload (record) { getFile(record.download_url, 'blob').then((file) => { // 直接下载文件传blob型 const reader = new FileReader() reader.readAsDataURL(file) reader.onload = (e) => { const a = document.createElement('a') // 获取文件名fileName a.download = record.file_name a.href = e.target.result document.body.appendChild(a) a.click() // 这样就触发浏览器下载文件了 document.body.removeChild(a) } }) }