vue项目通过axios请求实现下载excel文件功能
写在开头:通过a标签 <a href="文件下载地址"> </a>
也能实现文件的下载功能,前提是后端写的这个下载接口的请求方式是get
。
但是这种方式存在一个问题,使用a标签下载文件,请求接口的时候无法在请求头中携带token
,如果这个接口要求验证token信息
,那么a标签请求就会被拦截,不能完成下载,因此,就可以通过发送axios请求
来实现下载功能。
第一步:
- 页面中的dom元素绑定点击事件
<el-button
class="hollowBtn"
icon="iconfont iconxiazai"
@click="download"
>
下载
</el-button>
- 统一配置axios 的文件
src/api.js
import Axios from 'axios'
const axios = Axios.create({
baseURL: 'https://some-domain.com/api/',
// 如果请求花费了超过 `timeout` 的时间,请求将被中断
timeout: 5000,
})
//请求拦截
axios.interceptors.request.use(config => {
//如果调用的是登录接口,则把请求头中的token设置为null,如果是其他接口,则从本地存储中获取token
if (config.url === '/api/sys/user/login') {
config.headers['Authorization'] = null;
} else {
let token = sessionStorage.getItem("token")
config.headers['Authorization'] = token;
}
return config
}, error => { //请求错误处理
Promise.reject(error)
})
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
//把配置好的axios导出
export {axios }
- vue 项目 methods 里面的JS 部分
<script>
import { axios} from "@/api.js";
export default {
data(){},
methods :{
download() {
//这时的axios是已经携带了token信息的
axios({
method: 'get',
url: `/api/portrait/group/exprot`,
// 注意配置响应方式 responseType: 'blob'
responseType: 'blob'
}).then((res) => {
//接口请求成功之后完成以下操作
let blob = new Blob([res.data], { type: 'application/vnd.ms-excel' });
// 获取 获取响应头 heads 中的 filename 文件名
let temp = res.headers["content-disposition"].split(";")[1].split("Filename=")[1];
// 把 %E9%AB%98%E6%84%8F%E5%90%91%E5%AD%A6%E5%91%98303.xlsx 转化成文字
var fileName = decodeURIComponent(temp);
//创建一个 a 标签
const link = document.createElement('a')
//不显示a标签
link.style.display = 'none'
// 给a 标签的href属性赋值
link.href = URL.createObjectURL(blob);
link.setAttribute('download', fileName)
//把a标签插入页面中
document.body.appendChild(link)
link.click()
//点击之后移除a标签
document.body.removeChild(link)
}).catch(error => {
Message.error('下载失败')
console.log(error);
})
}
}
}
</script>
注意!!:
res.headers["content-disposition"]
有可能获取不到,另外一篇文章中有说明,点击查看原因
解决方法:
后端在这个接口的代码中加上以下代码:说明见另一篇文章:axios无法获取响应头headers的Content-Disposition