vue项目中需要实现下载文件,后端不是给到文件地址,而是返回二进制文件流。

相关知识:

后端响应给我们二进制流文件,我们需要拿到相关信息并创建一个a标签并实现click,然后给下载的文件起个名字。

给下载文件起名字有两种方式:(1)固定值+时间戳(一般都加上时间戳)

(2)后端将文件名放到response的headers中返回,我们取值当做文件名。我们此次需求为第二种,名称后端定。

后端放到响应头中的字段长什么样子呢?

大约如下:

(1)Access-Control-Expose-Headers:content-disposition

// 大意就是允许访问请求头中的content-disposition字段,window系统默认是允许获取的,但是macOS系统默认不允许,不允许获取我们就没办法动态获取文件名。所以后端需要设置允许访问才可以解决macOS下载时动态获取文件名的错误。可以如下设置:

response.setHeader("Access-Control-Expose-Headers", "content-disposition");

(2)charset:utf-8,如果文件名为中文,在macOS下载后文件名乱码,window默认utf-8所以没有乱码。需要后端单独设置一下即可解决macOS乱码问题。可以如下设置:

response.setHeader("charset", "utf-8");

(3)Content-Disposition:attachment; filename=%E6%B3%95%E9%99%A2%E6%89%A7%E8%A1%8C%E4%BA%BA%E6%95%B4%E5%90%882_liumin_20200316225515562.xml

这个就是后端追加到headers中的信息,比如文件名是什么,下载方式是什么。我们要获取的文件名就在这里。

附上后端代码片段

vue+axios 下载二进制流文件及兼容MacOS问题

vue实现代码:

     let token = getStore("token") ? JSON.parse(getStore("token")) : "" 

      let url = `${api.baseURL}/dataSource/downloadInitFile?fileType=${type}` //改为所需的url

      axios({

            url: url,

            method: "get",

            responseType: "blob", // 注明响应类型为blob

            headers: {

                token: token

            }

        }).then(r => {

            var headerInfo= r.headers//响应信息中的headers信息

            var disposition= headerInfo["content-disposition"] // 后端通常会将文件名放入到headers中的content-disposition

            filename = decodeURI(disposition.split(";")[1].split("filename=")[1]); 

            let createUrl = window.URL.createObjectURL(r.data)

            const a = document.createElement("a")

            a.href = createUrl

            a.download = filename

            document.body.appendChild(a)

            a.click()

            a.remove()

        })

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-09-11
  • 2022-12-23
  • 2022-01-16
  • 2021-08-18
  • 2021-12-28
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-01-14
  • 2022-12-23
  • 2021-10-12
  • 2021-08-23
  • 2022-12-23
相关资源
相似解决方案