前端下载文件时处理后端有可能返回文件流,有可能返回报错信息的情况。

问题描述:项目中导出excel向后端请求接口,当存在需要导出的文件时,后端直接返回文件流。

前端下载文件时处理后端有可能返回文件流,有可能返回报错信息的情况。_第1张图片

当出现错误信息时,后端返回错误信息,前端需要弹出提示用户。

前端下载文件时处理后端有可能返回文件流,有可能返回报错信息的情况。_第2张图片

但是在请求下载时,需要指定responseType为'blob':

前端下载文件时处理后端有可能返回文件流,有可能返回报错信息的情况。_第3张图片

 

 当返回信息时我们想根据res.data来判断是文件流还是JSON信息来进行对应的操作时会发现此时得到的res.data都是一个Blob对象,这是在接口请求时就定好了,改变不了的。

这个时候我们可以将Blob转为String字符串,尝试使用JSON.parse反序列化,如果存在错误信息 msg字段,那么就弹出信息提示,否则的话都走下载文件流程。

前端下载文件时处理后端有可能返回文件流,有可能返回报错信息的情况。_第4张图片

 

//导出excel
    exportExcel () {
      let loading = this.$loading({ text: "努力请求中~" });
      ExportKaiPiaoGTH(this.where).then(res => {
        loading.close();
        //获取文件名
        let headerArr = res.headers?.["content-disposition"]?.split(";") || [];
        let nameArr = headerArr[1]?.split("=") || [];
        let fileName = nameArr[1] || "";
        fileName = decodeURI(fileName);
        let blob = new Blob([res.data])
        //将Blob 对象转换成字符串
        let reader = new FileReader();
        reader.readAsText(blob, 'utf-8');
        reader.onload = () => {
          try {
            let result = JSON.parse(reader.result);
            if (result.msg) {
              this.$message.error(result.msg);
            } else {
              this.downloadBlob(blob, fileName);
            }
          } catch (err) {
            console.log(err);
            this.downloadBlob(blob, fileName);
          }
        }

      }).catch(err => {
        loading.close();
        this.$message.error(err.message);
      })
    },

    //将blob下载为文件
    downloadBlob (blob, fileName) {
      const downloadElement = document.createElement('a');
      const href = window.URL.createObjectURL(blob); //创建下载的链接
      downloadElement.href = href;
      downloadElement.download = fileName || '客户开票详情.xlsx'; //下载后文件名
      document.body.appendChild(downloadElement);
      downloadElement.click(); //点击下载
      document.body.removeChild(downloadElement); //下载完成移除元素
      window.URL.revokeObjectURL(href); //释放掉blob对象
    }

你可能感兴趣的:(前端)