axios文件下载使用后端传递的名称

发布于:2025-03-31 ⋅ 阅读:(24) ⋅ 点赞:(0)

java后端通过HttpServletResponse 返回文件流

在Content-Disposition中插入文件名
一定要设置Access-Control-Expose-Headers,代表跨域该Content-Disposition返回Header可读,如果没有,前端是取不到Content-Disposition的,可以在统一的配置里添加

response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setCharacterEncoding("UTF-8");
// 跨域暴露Header属性Content-Disposition
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
//test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(byType.getName() , StandardCharsets.UTF_8) + ".xls");

在这里插入图片描述

vue前端通过 axios接收文件

老生常谈的 blob或者arraybuffer
这里以arraybuffer举例

export const exportExcel=(data: Object)=>{
	return request.get( option: {
		url:'/scrm/customer/exportExcel'
		data,
		responseType:'arraybuffer'
	})
})

找你的axios封装

vue2找 request.js
vue3找service.ts
或者你们自己封装的文件
找到里边的响应拦截器

request.interceptors.response.use
service.interceptors.response.use

在返回成功的前提下单独处理
直接返回response
如果你们封装的axios跟没封装一样可以忽略

if (response.request.responseType === 'blob' 
	|| response.request.responseType === 'arraybuffer') {
	return response
}

封装个统一的方法
TS

const download = {
object: ({data, headers}, fileName :string, contentType: string) => {
    try {
      const uri =headers["content-disposition"].split(";")[1].split("filename=")[1];
      fileName = decodeURIComponent(uri)
      contentType = headers["content-type"]
    } catch (e) {
      console.error(e)
    }
    // 老一套blob 
	const blob = new Blob([data],{ type: contentType})
    const link = document.createElement('a')
    const href = window.URL.createObjectURL(blob) // 创建下载的链接
    link.href = href
    link.download = fileName
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(href)
  }
}

JS

 downloadObject(res, fileName, contentType) {
 	let data = res.data
 	let headers = res.headers
 	try {
      const uri =headers["content-disposition"].split(";")[1].split("filename=")[1];
      fileName = decodeURIComponent(uri)
      contentType = headers["content-type"]
    } catch (e) {
      console.error(e)
    }
    // 老一套blob 
	const blob = new Blob([data],{ type: contentType})
    const link = document.createElement('a')
    const href = window.URL.createObjectURL(blob) // 创建下载的链接
    link.href = href
    link.download = fileName
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(href)
 }

调用

	exportExcel({//请求参数}).then(res => {
		// vue3
		download.object(res,'','')
		// vue2
		this.downloadObject(res)
	})

最后

需要注意的一共有两个点
第一 后端必须配置
response.setHeader(“Access-Control-Expose-Headers”, “Content-Disposition”);
第二 axios返回拦截器一定要返回完整的response,不能返回经过加工的response.data