后台数据流数据下载并判定异常--Blob&FileReader

业务需求

要实现一个文件下载功能,这个下载的文件是后台根据数据处理之后返回的数据流,并且如果文件无法下载,或者是打包文件时出现异常,数据流里面直接返回异常,前段需要输出异常提示。

解决思路

为了实现这样的需求,想到了用 Blob 去接收数据,然后使用 FileReader 去读取无法下载的文件的异常返回,能够下载的文件则走下载的流程(如果是IE10以上的浏览器,则运行 navigator.msSaveBlob(blob, filename);如果是其他chrome内核的浏览器,则通过创建a标签的形式来进行下载)

Internet Explorer 10msSaveBlobmsSaveOrOpenBlob 方法允许用户在客户端上保存文件,方法如同从 Internet 下载文件,这是此类文件保存到“下载”文件夹的原因。 关于msSaveBlob与msSaveOrOpenBlob

代码

export async function apiOutputSelfMarkTable(agr = {}) {
  // 获取token
  let token = window.localStorage.getItem('token')
  // 定义接口api
  let url = '/proxy/fydj/perfCheck/exportSelfMarkTable' 
  // 发送请求
  axios({
    method: 'post', // post方法
    url,    
    data: agr,
    responseType: 'blob',
    headers: {
      Authorization: token,
    },
  })
    .then(async res => {
      const blob = new Blob([res.data])
      // 判断是否为数据流文件,如果不是则输出错误原因,
      // 如果是则下载该文件
      if (res.data.type !== 'application/octet-stream') {
        let reader = new FileReader()
        reader.readAsText(blob)
        // 因为render.readAsText()是异步的,
        // 所以下面必修调用onload来加载之前输出的结果
        reader.onload = function () {
          //读取完毕后输出结果
          message.error(this.result)
        }
        return
      } else {
        // 定义正则
        let negx = new RegExp('attachment;filename=', 'g')
        let Str = res.headers['content-disposition']
        // 获取文件名称
        let filename = decodeURI(Str.replace(negx, ''))
        if ('download' in document.createElement('a')) {
          // 非IE下载
          const elink = document.createElement('a')
          elink.download = filename
          elink.style.display = 'none'
          elink.href = URL.createObjectURL(blob)
          document.body.appendChild(elink)
          elink.click()
          URL.revokeObjectURL(elink.href) // 释放URL 对象
          document.body.removeChild(elink)
          console.log('下载第二步')
        } else {
          // IE10+下载
          navigator.msSaveBlob(blob, filename)
        }
      }
    })
    .catch(err => {
      console.log(err)
    })
}
readAsText 方法可以将 Blob 或者  File []( https://developer.mozilla.org... 对象转根据特殊的编码格式转化为内容(字符串形式)

这个方法是异步的,也就是说,只有当执行完成后才能够查看到结果,如果直接查看是无结果的,并返回undefined

也就是说必须要挂载 实例下的 onloadonloadend 的方法处理转化后的结果 (引自MDN文档)

你可能感兴趣的:(前端,react.js,axios)