日常工作中我们经常遇到文件下载的需求, 模板下载、 附件下载、 配套工具下载等等, 针对这些场景我总结了几个下载方案分享给大家
方案一
使用我们最常见的 a 标签
<a href="https://nodejs.org/dist/v18.15.0/node-v18.15.0-x64.msi" download=''>下载Node.js</a>
最终效果就像这样: 下载 Node.js
方案二
自己封装 Ajax , 为什么需要这种方案呢, 因为有时候接口是需要鉴权的, a 标签是无法添加 token 之类的
//封装下载公用函数, 提供传文件名、后端接口
function downloadFileHttp(fileName, url) {
const XHR = new XMLHttpRequest()
const BASEURL = window.AppConfig.baseUrl //项目配置全局的请求url, 大同小异
XHR.open('get', BASEURL + url)
//设置请求头信息
XHR.setRequestHeader('X-Token', getCookie('app-token'))
XHR.responseType = 'blob'
XHR.onload = function() {
if (this.status == 200) {
let blob = this.response
if (window.navigator.msSaveOrOpenBlob) { //这个判断主要用来兼容浏览器
navigator.msSaveBlob(blob)
} else {
//像谷歌可以不需要这个判断, 直接用下面这段
let tagA = document.createElement('a')
tagA.href = createObjectURL(blob)
tagA.download = filename
tagA.style.display = "none"
tagA.click() //做模拟点击下载
}
}
}
XHR.send()
}
然后页面需要用的时候引入调用即可
//demo.vue
<template>
<button @click="handleDown">下载附件</button>
</template>
import downloadFileHttp from './utils'
export default {
methods: {
handleDown() {
downloadFileHttp('部署流程整理', '/deploy/template/download')
}
}
}
方案三
有些同学就要问了:有了前两种方案,还需要第三种方案吗?
答案是要的, 这时候来了个需求: 接口要请求体传参, 很明显上面那种方法get只支持 query 传参(拼接在接口后面) XHR.send(params) 只支持post哈。
那又有人问了为什么会有这种需求呢?
我想到的是可能出于 安全 又或者出于 美观 考虑, 我们就不想拼接在请求链接里, 这时候方案二就无法满足了, 这时候我们可以利用 axios,
//demo.vue
<template>
<button @click="handleDown">下载附件</button>
</template>
import axios from 'axios'
export default {
methods: {
handleDown( file ) {
axios({
url: '/person/template/download',
method: 'get',
headers: {
'X-Token': getCookie('app-token'),
},
responseType: 'blob',
params: {
filePath: file.path,
fileSize: '100M',
...
//这里可以传一大堆你想要的
}
}).then(res => {
if (res.status === 200) {
let a = document.createElement('a')
a.href = window.URL.createObjectURL(res.data)
a.download = file.name
a.style.display = 'none'
a.click()
}
})
}
}
}