美文网首页
前端实现文件流下载【axios】

前端实现文件流下载【axios】

作者: cuttlefish | 来源:发表于2022-08-18 12:51 被阅读0次

以下是一个拿到流数据后的下载操作代码实现

// download.js


// 处理下载流
export const download = (content, fileName) => {
  const blob = new Blob([content]); // 创建一个类文件对象:Blob 对象表示一个不可变的、原始数据的类文件对象
  // URL.createObjectURL(object) 表示生成一个 File 对象或 Blob 对象
  const url = window.URL.createObjectURL(blob);
  const dom = document.createElement("a"); // 设置一个隐藏的 a 标签,href 为输出流,设置 download
  dom.style.display = "none";
  dom.href = url;
  dom.setAttribute("download", fileName); // 指示浏览器下载 url,而不是导航到它;因此将提示用户将其保存为本地文件
  document.body.appendChild(dom);
  dom.click();
  document.body.removeChild(dom); // 下载完成移除元素
  window.URL.revokeObjectURL(url); // 释放掉 blob 对象
};

/**
 * 获取http响应的文件名
 * @param {*} str http响应header中content-disposition字段
 * @returns
 */
export const getFileName = (str) => {
  const arr = str.split(";");
  // filename*=
  let temp = arr.find((e) => e.startsWith("filename*="));
  if (temp) {
    // 默认utf-8模式
    const index = temp.lastIndexOf("'");
    return decodeURIComponent(temp.slice(index + 1));
  }
  // filename=
  temp = arr.find((e) => e.startsWith("filename="));
  if (temp) {
    return temp.replace("filename=", "");
  }
  throw Error(
    "未在响应头获取到文件名(请检查响应头字段大小写),且默认自定义文件名未传!!"
  );
};

/**
 * 处理下载流
 * @param {*} response 完整的http响应
 * @param {*} fileName 自定义的文件名(如果没传从response中拿到)
 */
export const downloadV2 = (response, fileName = false) => {
  const name = fileName ? fileName : response.headers["content-disposition"];
  let filename = "";
  try {
    filename = getFileName(name);
  } catch (error) {
    console.error(error);
    return;
  }
  const blob = new Blob([response.data]); // 创建一个类文件对象:Blob 对象表示一个不可变的、原始数据的类文件对象
  // URL.createObjectURL(object) 表示生成一个 File 对象或 Blob 对象
  const url = window.URL.createObjectURL(blob);
  const dom = document.createElement("a"); // 设置一个隐藏的 a 标签,href 为输出流,设置 download
  dom.style.display = "none";
  dom.href = url;
  dom.setAttribute("download", filename); // 指示浏览器下载 url,而不是导航到它;因此将提示用户将其保存为本地文件
  document.body.appendChild(dom);
  dom.click();
  document.body.removeChild(dom); // 下载完成移除元素
  window.URL.revokeObjectURL(url); // 释放掉 blob 对象
};


axios遇到流下载异常返回JSON时的处理

    // 如果是下载文件流报错,转换错误信息为json响应
    if (responseType === "blob") {
      let resBlob = res.data;
      return new Promise(function (resolve) {
        let reader = new FileReader();
        reader.readAsText(resBlob, "utf-8");
        reader.onload = () => {
          let ress = JSON.parse(reader.result);
          if (ress.code !== 0) {
            // 提示错误的信息
            Message({
              showClose: true,
              message: ress.msg,
              type: "error",
            });
            return resolve(ress);
          }
        };
      });
    }

相关文章

网友评论

      本文标题:前端实现文件流下载【axios】

      本文链接:https://www.haomeiwen.com/subject/rksegrtx.html