在vue项目中使用axios实现post方式获取二进制流下载文件

需求

点击导出下载表格对应的excel文件

vue项目中,使用的axios,后台java提供的post接口api

实现

第一步,在axios请求中加入参数,表示接收的数据为二进制文件流

responseType: 'blob'

第二步,在拿到数据流之后,把流转为指定文件格式并创建a标签,模拟点击下载,实现文件下载功能

let blob = res.data
let reader = new FileReader()
reader.readAsDataURL(blob)
reader.onload = (e) => {
    let a = document.createElement('a')
    a.download = fileName
    a.href = e.target.result
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
}

问题

使用axios会出现无法拿到java后端给出的Content-Disposition中的文件名

注意的是,浏览器中可以看到header中有信息,但是无法通过axiosres.header获取到

这种情况需要后端设置header

Access-Control-Expose-Headers: Content-Disposition

有可能后端加了之后还是获取不到,那么让后端单独加一个fileName字段即可

response.setContentType("multipart/form-data");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + UUID.randomUUID().toString() + ".xlsx");
response.setHeader("FileName", UUID.randomUUID().toString() + ".xlsx");
response.setHeader("Access-Control-Expose-Headers", "FileName")

总结

完整的axios代码

axios.post({
    url:`url`,
    method:`post`,
    responseType: 'blob'
}).then(res => {
    let blob = res.data
    let reader = new FileReader()
    reader.readAsDataURL(blob)
    reader.onload = (e) => {
        let a = document.createElement('a')
        a.download = `fileName.xlsx`
        a.href = e.target.result
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
    }
})