Vue.js根据后端返回文件流,通过post请求下载、预览文件,并兼容当后台抛出异常时捕获错误信息。

由于后端返回的是文件流,需要前端对返回的文件流进行处理

1.先是声明发送请求的返回格式: responseType: 'blob'

  自定义下载文件请求方法:

  

/**
 * 封装文件下载post请求
 * @param url
 * @param data
 * @returns {Promise}
 */
export function fileDownload (url, data = {}){
  return new Promise((resolve,reject) => {
    axios.post(url, data,{
      responseType: 'blob'
    })
      .then(response => {
        resultsProcessing(response,resolve);
      }).catch(err=>{
        reject(err);
      });
  });
}

 

2. 模拟a标签自动下载文件

  请求的信息:

  下载异常时:

返回的结果信息:

 

下载正常时:

  

    //点击文件列表的钩子
    handlePreview(file, fileList) {
      let _that = this;
      let fileUrl = xxxx;
      let downloadUrl = process.env.BASE_API + xxxx;
      
      this.$downloadPost(downloadUrl,param).then(res => {
        let type = res.data.type;
        let reader = new FileReader();
        reader.onload = function (event) {
          let content = reader.result;
          try {
            //普通对象数据,后台抛出异常
            let message = JSON.parse(content); // 错误信息
            if (message.code !== "1000") {
              _that.$message.error(message.msg);
              return;
            }
          } catch (err) {
            //解析成对象失败,是正常的文件流
              let fileName =  xxxxx;
              _that.download(res, fileName);
          }
        };
        reader.readAsText(res.data);
        return true;
      });
    },
    //下载文件
    download(res, fileName) {
      console.log(res);
      // let blob = new Blob([data.data]);
      if ("download" in document.createElement("a")) {
        // 非IE下载
        const elink = document.createElement("a");
        elink.download = fileName;
        elink.style.display = "none";
        elink.href = URL.createObjectURL(res.data);
        document.body.appendChild(elink);
        elink.click();
        URL.revokeObjectURL(elink.href); // 释放URL 对象
        document.body.removeChild(elink);
      } else {
        // IE10+下载
        navigator.msSaveBlob(blob, fileName);
      }
    },

 

2. 后端java代码

String fileUrl = attachment.getFileUrl();
        if (StringUtils.isBlank(fileUrl)) {
            log.error("文件路径不能为空");
            throw new Exception("文件路径不能为空");
        }
        if (!fileUrl.contains(sp)) {
            log.error("文件路径异常");
            throw new Exception("文件路径异常");
        }
        byte[] bytes = fastDfsUtil.downloadFile(fileUrl);
        if (null == bytes && bytes.length < 1) {
            log.error("文件下载异常");
            throw new Exception("文件下载异常");
        }

        response.addHeader("Pragma", "No-cache");
        response.addHeader("Cache-Control", "No-cache");
        response.setCharacterEncoding("UTF-8");
        String fileName = attachment.getName();
        String suffix = fileUrl.split("\\.")[1];
        if (StringUtils.isBlank(fileName)) {
            fileName = String.valueOf(System.currentTimeMillis())+sp+suffix;
        }
        // 处理get请求的中文乱码问题
        log.debug("------------------文件名称-----------------"+fileName);
        fileName = new String(fileName.getBytes("ISO8859-1"), "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
        String s = fileUrl.split("/")[fileUrl.split("/").length - 1];
        log.info("下载文件-》文件类型{}",request.getServletContext().getMimeType(s));
        response.setContentType(request.getServletContext().getMimeType(s)+";charset=utf-8");
        OutputStream out = response.getOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(out);
        try {
            bos.write(bytes,0,bytes.length);
            bos.flush();
        } catch (Exception e) {
            log.error("文件下载异常{}",e);
            throw new Exception("文件下载异常");
        } finally {
            if (bos != null) {
                bos.close();
            }
            if (out != null) {
                out.close();
            }
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hi,all

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>