fetch下载文件流的报错处理并且加上异步变同步实现

167 阅读1分钟
options是发送请求的对象参数
const options={}
options.method='POST'
options.headers={
  Accept:'application/json,text/plain,*/*',
  'Content-Type':'application/x-www-form-urlencoded'
}
options.body={
  params1:'xxx'
}

/**
 * @description: fetch下载文件流的报错处理并且加上异步变同步实现
 * checkStatus 检查服务器请求是否到达 status ?==200
 * res.blob 把返回值转换成文件流
 * @return {*}
 * @author: 李思甜
 */
const download=()=>{
  return fetch(url,options).then(checkStatus).then(res=>res.blob().then(blob=>{
    return new Promise((resolve,reject)=>{
      // FileReader文件读取
      const reader=new FileReader()
      // 初始化把传入的文件流读取解析
      reader.onload=e=>{
        // 获取解析后的文件内容,两种情况 一种是正常返回的流,还有一种情况是后台500 返回错误的异常对象
        const text=reader.result
        try {
          // 读取内容有个特殊情况 如果上传内容是纯数字的txt文件,此时text读取的不是流而是文件内容,
          // 而纯数字又恰好是合法的json字符串,为了避免这种情况 需要把data再来判断下是否是后台返回的对象
          const data=JSON.parse(text)
          if(data.error_code){
            // 弹框弹出异常信息
            error(data.error_code,data.error_message)
            resolve({success:false})
          }else{
            // 1的特殊情况 手动进入异常进行文件下载
            throw new Error('this is a Error')
          }
        } catch (error) {
          // 获取请求头的文件名 看需求要不要 如果要就必须要返回不然会报错
          let newFileName=res?.headers?.get('Content-Disposition')?.split(';')[1]?.split('=')[1]
          // 如果有乱码就加解码 不然就不用
          newFileName=decodeURIComponent(newFileName)
          // 以下是下载逻辑
          let a=document.createElement('a')
          const fileUrl=window.URL.createObjectURL(blob)
          a.href=fileUrl
          a.download=newFileName || 'test.txt'
          a.click()
          window.URL.revokeObjectURL(url)
          resolve({success:true})
        }
      }
      reader.readAsText(blob)
    })
  }))
}