前端请求文件数据流

334 阅读2分钟

前端设置请求的responseType为'blob'

指定响应的数据类型为二进制数据流,请求成功会返回文件流内容。

axios.get(url, { responseType: 'blob' })

转为blob对象

使用new Blob()将请求返回的文件流转为blob对象。

axios
  .get(url, { responseType: 'blob' })
  .then(res => {
    const blob = new Blob([res.data]);
  })

将blob对象转成URL进行显示或下载

使用URL.createObjectURL()将blob对象转为URL。

axios
  .get(url, { responseType: 'blob' })
  .then(res => {
    const blob = new Blob([res.data]);
    const url = URL.createObjectURL(blob);
  })

请求文件流并下载

/**
 * @param url 接口请求地址
 * @param fileName 下载的文件名称
 * @returns Promise
 */
export const downloadFile = async(url: string, fileName: string) => {
  return axios
    .get(url, { responseType: 'blob' })
    .then(res => {
      const blob = new Blob([res.data]);
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = fileName;
      link.click();
      // 释放一个之前已经存在的、通过调用URL.createObjectURL()创建的URL对象
      URL.revokeObjectURL(url);
      message.success("下载成功");
      return res;
    })
    .catch((error) => {
      message.error("下载失败");
      return Promise.reject(error);
    })
}

请求文件流失败时的处理

请求的responseType设置为'blob'时,请求成功会返回文件流内容。但是请求失败的时候后端返回的是json,这种情况在我们通常封装的axios中判断后端返回的code值就不适用了,需要进行特殊处理。

  • 将responseType设置为'json',请求成功之后将json格式转化成blob在进行导出。
  • 将responseType设置为'blob',请求失败之后将blob格式转化成json格式再进行错误提示。(采用的形式)
/**
 * @param url 接口请求地址
 * @param fileName 下载的文件名称
 * @returns Promise
 */
export const downloadFile = async(url: string, fileName: string) => {
  return axios
    .get(url, { responseType: 'blob' })
    .then(res => {
      // 请求失败之后的处理 (请求失败时的content-type为application/json)
      if (res.headers['content-type'] === 'application/json') {
        // 将blob转为json进行解析
        const reader = new FileReader();
        reader.readAsText(res.data, 'utf-8');
        reader.onload = function() {
          const parseObj = JSON.parse(reader.result);
          message.error(parseObj.msg || '导出失败');
        }
        return Promise.reject('导出失败');
      }
      const blob = new Blob([res.data]);
      const url = URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = fileName;
      link.click();
      // 释放一个之前已经存在的、通过调用URL.createObjectURL()创建的URL对象
      URL.revokeObjectURL(url);
      message.success("下载成功");
      return res;
    })
    .catch((error) => {
      message.error("下载失败");
      return Promise.reject(error);
    })
}