使用Axios下载文件,下载失败可弹出提示

使用Axios下载文件

近日在做vue项目中,使用Axios下载文件遇到了问题,特此记录,希望可以帮到同样遇到问题的小伙伴
Axios请求如下

export function downloadPolicyFile(queryParam) {
  return request.post('/frontend/dzdz/downloadPDF', queryParam, { responseType: 'blob' })
}

这里需要注意的是,一定要指定responseType为blob,后台成功时会返回文件流,如果不成功返回json
公共下载文件方法如下

  // 公共下载保单方法
    download(queryParam) {
      downloadPolicyFile({ policyNo: queryParam }).then(res => {
        const Base64 = require('js-base64').Base64
        var reader = new FileReader()
        // 这里读取blob
        reader.readAsBinaryString(res)
        const _this = this
        reader.onload = function(evt) {
          if (evt.target.readyState === FileReader.DONE) {
            try {
              // 如果能被解析成json,则说明下载失败
              const errorInfo = JSON.parse(evt.target.result)
              if (errorInfo.flag) {
              //由于读取时汉字会乱码,与后台约定错误信息返回base64格式
             _this.$message.error(Base64.decode(errorInfo.msg))
              }
            } catch (e) {
              const url = window.URL.createObjectURL(new Blob([res]))
              const link = document.createElement('a')
              link.style.display = 'none'
              link.href = url
              // 获取文件名
              // download 属性定义了下载链接的地址而不是跳转路径
              link.setAttribute('download', queryParam + '.pdf')
              document.body.appendChild(link)
              link.click()
              document.body.removeChild(link)
              window.URL.revokeObjectURL(url)
            }
          }
        }
      }).catch(err => {
        this.$message.error(err)
      })

这种方法不兼容ie11,首先是readAsBinaryString这个方法不兼容,所以重写了readAsBinaryString方法

if (!FileReader.prototype.readAsBinaryString) {
          FileReader.prototype.readAsBinaryString = function(fileData) {
            let binary = ''
            const pt = this
            const reader = new FileReader()
            reader.onload = function(e) {
              var bytes = new Uint8Array(reader.result)
              var length = bytes.byteLength
              for (var i = 0; i < length; i++) {
                binary += String.fromCharCode(bytes[i])
              }
              pt.content = binary
              pt.onload(pt)
            }
            reader.readAsArrayBuffer(fileData)
          }
        }

改进之后的代码如下,可以兼容ie11

download(queryParam) {
      downloadPolicyFile({ policyNo: queryParam }).then(res => {
        const Base64 = require('js-base64').Base64
        var reader = new FileReader()
        // ie11不兼容readAsBinaryString方法,故新增该方法
        if (!FileReader.prototype.readAsBinaryString) {
          FileReader.prototype.readAsBinaryString = function(fileData) {
            let binary = ''
            const pt = this
            const reader = new FileReader()
            reader.onload = function(e) {
              var bytes = new Uint8Array(reader.result)
              var length = bytes.byteLength
              for (var i = 0; i < length; i++) {
                binary += String.fromCharCode(bytes[i])
              }
              pt.content = binary
              pt.onload(pt)
            }
            reader.readAsArrayBuffer(fileData)
          }
        }
        reader.readAsBinaryString(res)
        const _this = this
        reader.onload = function(evt) {
          try {
            // 如果能被解析成json,则说明失败
            let errorInfo
            // 兼容ie11
            if (window.navigator.msSaveOrOpenBlob) {
              errorInfo = JSON.parse(evt.content)
            } else {
              errorInfo = JSON.parse(evt.target.result)
            }
            if (errorInfo.flag) {
              _this.$message.error(Base64.decode(errorInfo.msg))
            }
          } catch (e) {
            const fileName = queryParam + '.pdf'
            // 兼容ie11下载blob
            if (window.navigator.msSaveOrOpenBlob) {
              try {
                const blobObject = new Blob([res])
                window.navigator.msSaveOrOpenBlob(blobObject, fileName)
              } catch (e) {
                console.log(e)
              }
              return
            }
            const url = window.URL.createObjectURL(new Blob([res]))
            const link = document.createElement('a')
            link.style.display = 'none'
            link.href = url
            // 获取文件名
            // download 属性定义了下载链接的地址而不是跳转路径
            link.setAttribute('download', fileName)
            document.body.appendChild(link)
            link.click()
            document.body.removeChild(link)
            window.URL.revokeObjectURL(url)
          }
        }
      }).catch(err => {
        this.$message.error(err)
      })
    },

版权声明:本文为weixin_37633749原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。