关于前端下载后端文件的问题,如何解决?

vue项目需要做一个从后端下载excel文件的功能,我获取后端的blob文件流,再转成xlsx文件,自己测试下载的时候没有问题,但是后端打包部署项目到生产中,下载的excel文件变成的txt文件,这个txt文件里的内容是传过来的二进制流,这是什么情况?

img

img

JavaScript代码:


    download() {
      this.$api.report.pubDosingKcls1(this.reportForm).then(res => {
        let a = res.headers['content-type']
        if (a === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
          const blob = new Blob([res.data])
          // 获取 获取响应头 heads 中的 filename 文件名
          const temp = res.headers['content-disposition'].split(';')[1].split('filename=')[1];
          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)
          URL.revokeObjectURL(link.href); // 释放内存
          setTimeout(() => {
            loading.close();
          }, 3000)
          this.dialogReport = false
        }else {
          let reader = new FileReader()
          reader.onload = function () {
            let res = reader.result
            let result = JSON.parse(res)
            Message({
              message: result.msg,
              type: 'error'
            })
          }
          reader.readAsText(res.data)
          loading.close()
        }
      })
      const loading = this.$loading({
        lock: true,
        text: '下载中,请耐心等待',
        spinner: 'el-icon-loading',
        background: 'rgba(255, 255, 255, 0.9)',
        target: document.querySelector('.table')
      });
    },

接口:


  download: params => {
    return $axios.post('/report/pub_kcls_1/', params,
        {responseType: 'blob'})
  },

在你的代码中,使用的是Blob来将服务器响应转换为可下载的文件。这种方法通常是可行的,但是在某些情况下可能会遇到问题。在这种情况下,服务器响应的内容可能包含不正确的数据类型或编码,导致浏览器无法正确识别文件类型并且下载的文件变成乱码。

为了解决这个问题,可以尝试使用第三方库file-saver,这个库可以让你更方便地下载文件,并且可以自动处理文件类型和编码。

安装:

npm install file-saver --save

使用:

import { saveAs } from 'file-saver'

// 下载excel文件
this.$api.report.pubDosingKcls1(this.reportForm).then(response => {
  const fileName = getFileName(response.headers['content-disposition'])
  const contentType = response.headers['content-type']
  const blob = new Blob([response.data], { type: contentType })

  // 使用file-saver库下载文件
  saveAs(blob, fileName)
})

其中,getFileName函数用于从响应头中解析出文件名:

function getFileName(contentDisposition) {
  const match = contentDisposition.match(/filename="(.+)"/)

  if (match && match.length > 1) {
    return match[1]
  } else {
    return 'unknown'
  }
}

这个方法可能会解决你遇到的问题,让你的下载文件功能正常工作。

看下 content-disposition 返回的文件名后缀是什么