前言:项目实现点击下载功能,通过调一个接口,给后端传一个filePath的参数,后端返回fileName(这个fileName就是所要下载的文件名称),response返回的数据就是下载的文件的内容。(还有个重点,后端传输的是二进制流数据,前端在接口里面获取的时候需要对response类型进行定义)

一、前端遇到需要下载excel表时候的做法

问题1、如下图:fileName是存储在headers里面的,不能在response里面获取,他是和内容分开的,怎么获取是个关键

let fileNames = res.headers['content-disposition'] //获取到Content-Disposition;filename
let regFileNames = fileNames.match(/=(.*)$/)[1]; //文件名称  截取=后面的文件名称

问题2、点击下载

let fileNames = response.headers['content-disposition'] // 获取到Content-Disposition;filename
let regFileNames = fileNames.match(/=(.*)$/)[1] // 文件名称  截取=后面的文件名称
let content = response.data
let url = window.URL.createObjectURL(content)
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', decodeURI(regFileNames))
document.body.appendChild(link)
link.click()

二、实际情况中遇到过别的问题(后端没有给前端主动返回content-disposition,后端需要给前端传的参数)

如果后端返回的response中没有可以获取的content-disposition,那么说明后端没有给前端传递数据。

默认情况下,header只有六种 simple response headers (简单响应首部)可以暴露给外部:

  • Cache-Control
  • Content-Language
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

这里的暴露给外部,意思是让客户端可以访问得到,既可以在 Network 里看到,也可以在代码里获取到他们的值。

上面问题提到的 content-disposition 不在其中,所以即使服务器在协议回包里加了该字段,但因没“暴露”给外部,客户端就“看得到,吃不到”。

而响应首部 Access-Control-Expose-Headers 就是控制“暴露”的开关,它列出了哪些首部可以作为响应的一部分暴露给外部。

所以如果想要让客户端可以访问到其他的首部信息,服务器不仅要在heade里加入该首部,还要将它们在 Access-Control-Expose-Headers 里面列出来

解决办法

后端设置:

  response.setHeader("Access-Control-Expose-Headers", "Content-Disposition")

Logo

前往低代码交流专区

更多推荐