业务需要

要实现一个文件下载性能,这个下载的文件是后盾依据数据处理之后返回的数据流,并且如果文件无奈下载,或者是打包文件时出现异常,数据流外面间接返回异样,前段须要输入异样提醒。

解决思路

为了实现这样的需要,想到了用 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文档)