跳转链接 下载链接 自定义处理 XMLHttpRequest 对象来发起 HTTP 请求

发布时间 2024-01-02 10:58:14作者: yoona-lin

import {
  saveAs
} from 'file-saver';

/**
 * @description:  JavaScript 动态生成的 a 标签进行下载,
 * * * * * * * * *可以使用 XMLHttpRequest 对象来发起 HTTP 请求,并在请求完成后获取响应数据
 * @param {*} url 请求地址
 * @param {*} isOpenNew 是否打开新标签页
 * @param {*} resType 请求类型
 * @param {*} jsonData POST请求的body体
 * @return {*}
 */
export function openUrl(url, isOpenNew, resType = "GET", jsonData = "") {
  const xhr = new XMLHttpRequest();
  xhr.open(resType, url, true);
  xhr.responseType = 'blob'; // 表示返回的数据是二进制流对象
  // 携带请求头
  // h5测试
  if (process.env.NODE_ENV == "development") {
    xhr.setRequestHeader(
      "Authorization",
      `Bearer ${process.env.VUE_APP_API_TOKEN}`
    );
    xhr.setRequestHeader(
      "X-Oars-Token",
      `${process.env.VUE_APP_API_TOKEN}`
    );
  } else {
    // 上线阶段,自动获取登录的 token localStorage Key:  IDAAS_BEARER_TOKEN
    let IDAAS_BEARER_TOKEN = localStorage.getItem("IDAAS_BEARER_TOKEN") || "";
    if (IDAAS_BEARER_TOKEN) {
      xhr.setRequestHeader(
        "Authorization",
        `Bearer ${IDAAS_BEARER_TOKEN}`
      );
    }

  }

  // 在 handleDownloadSuccess 中获取响应数据并创建下载链接
  const handleDownloadSuccess = function (event) {
    const blob = xhr.response;
    console.log('blob', blob)
    const downloadUrl = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = downloadUrl;
    if (isOpenNew) {
      link.setAttribute('target', '_blank')
    }
    // link.download = 'file.pdf';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(downloadUrl);
  }

  // handleStateChange 中判断请求的状态,并处理请求失败的情况
  const handleStateChange = function (event) {
    if (xhr.readyState === XMLHttpRequest.DONE) {
      if (xhr.status === 200) {
        // 原生数据流处理
        // 请求成功,处理响应数据

        console.log('xhr.response', xhr.response);
        // new FileReader() 解析,得到的字符串如何转成对象
        // 创建一个 FileReader 对象
        const reader = new FileReader();
        // 当读取完成时执行的回调函数
        reader.onload = function () {
          // 读取结果是一个字符串
          const result = reader.result;
          // console.log(result);
          // console.log(result.indexOf('"code":-1'))
          // 处理请求采购但是"code":-1'报错
          if (result.indexOf('"code":-1') != -1) {
            window.alert(`下载失败!${result}`);
          } else {
            // 获取文件名
            // getResponseHeader() 函数获取响应头中的 Content-Disposition 字段,该字段包含文件名
            var contentDisposition = xhr.getResponseHeader('content-disposition');
            var fileName = '';
            if (contentDisposition && contentDisposition.indexOf('attachment') !== -1) {
              var fileNameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
              var matches = fileNameRegex.exec(contentDisposition);
              if (matches != null && matches[1]) {
                fileName = decodeURIComponent(matches[1].replace(/['"]/g, ''));
              }
            }
            // a标签模式
            // const blob = xhr.response;
            // const downloadUrl = URL.createObjectURL(blob);
            // const link = document.createElement('a');
            // link.setAttribute('href', downloadUrl)
            // link.setAttribute('id', 'd2admin-link-temp')
            // link.download = fileName || "未命名.xlsx";
            // if (isOpenNew) {
            //   link.setAttribute('target', '_blank')
            // }
            // document.body.appendChild(link);
            // link.click();
            // document.body.removeChild(link);
            // URL.revokeObjectURL(downloadUrl);

            // openUrlBase(url, isOpenNew);

            // let a = document.createElement('a')
            // a.setAttribute('href', url)
            // if (isOpenNew) {
            //   a.setAttribute('target', '_blank')
            // }
            // a.setAttribute('id', 'd2admin-link-temp')
            // document.body.appendChild(a)
            // // error事件监听器
            // a.addEventListener('error', handleDownloadError);
            // console.log('22222', 22222)
            // a.click()
            // document.body.removeChild(a)

            // file-saver处理
            const blob = xhr.response;
            // console.log('fileName', fileName)
            // saveAs没有打开新标签页方法
            // 打开新标签页方法使用a标签模式
            saveAs(blob, fileName || "未命名.xlsx");
            // 触发两次下载
            // let urlCopy = URL.createObjectURL(blob);
            // window.open(urlCopy);
          }

        };
        // 读取 Blob 对象的内容
        reader.readAsText(xhr.response);
        return
        // 获取文件名
        // getResponseHeader() 函数获取响应头中的 Content-Disposition 字段,该字段包含文件名
        var contentDisposition = xhr.getResponseHeader('content-disposition');
        var fileName = '';
        if (contentDisposition && contentDisposition.indexOf('attachment') !== -1) {
          var fileNameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
          var matches = fileNameRegex.exec(contentDisposition);
          if (matches != null && matches[1]) {
            fileName = decodeURIComponent(matches[1].replace(/['"]/g, ''));
          }
        }
        // a标签模式
        // const blob = xhr.response;
        // const downloadUrl = URL.createObjectURL(blob);
        // const link = document.createElement('a');
        // link.setAttribute('href', downloadUrl)
        // link.setAttribute('id', 'd2admin-link-temp')
        // link.download = fileName || "未命名.xlsx";
        // if (isOpenNew) {
        //   link.setAttribute('target', '_blank')
        // }
        // document.body.appendChild(link);
        // link.click();
        // document.body.removeChild(link);
        // URL.revokeObjectURL(downloadUrl);

        // openUrlBase(url, isOpenNew);

        // let a = document.createElement('a')
        // a.setAttribute('href', url)
        // if (isOpenNew) {
        //   a.setAttribute('target', '_blank')
        // }
        // a.setAttribute('id', 'd2admin-link-temp')
        // document.body.appendChild(a)
        // // error事件监听器
        // a.addEventListener('error', handleDownloadError);
        // console.log('22222', 22222)
        // a.click()
        // document.body.removeChild(a)

        // file-saver处理
        const blob = xhr.response;
        console.log('fileName', fileName)
        saveAs(blob, fileName || "未命名.xlsx");

      } else {
        // 处理请求失败报错
        console.log('xhr.response', xhr.response);
        // 创建一个 FileReader 对象
        const reader = new FileReader();
        // 当读取完成时执行的回调函数
        reader.onload = function () {
          // 读取结果是一个字符串
          const result = reader.result;
          console.log(result);
          window.alert(`下载失败!${result}`);
        };
        // 读取 Blob 对象的内容
        reader.readAsText(xhr.response);
        // 请求失败,处理错误情况
        console.error('下载失败,HTTP 状态码为', xhr.status);
        // 或者
        // window.alert('下载失败,请检查!');
      }
    }
  }
  // xhr.addEventListener('load', handleDownloadSuccess);
  xhr.addEventListener('readystatechange', handleStateChange);

  // 不生效
  // xhr.addEventListener('error', handleDownloadError);
  if (resType == "GET") {
    xhr.send();
  } else {
    // resType == "POST"
    xhr.send(jsonData);
  }

}

// function handleDownloadSuccess(event) {
//   const blob = xhr.response;
//   console.log('blob', blob)
//   const downloadUrl = URL.createObjectURL(blob);
//   const link = document.createElement('a');
//   link.href = downloadUrl;
//   // link.download = 'file.pdf';
//   document.body.appendChild(link);
//   link.click();
//   document.body.removeChild(link);
//   URL.revokeObjectURL(downloadUrl);
// }

/**
 * @description: a标签打开url
 * @param {*} url 地址
 * @param {*} isOpenNew 是否打开新页面
 * @return {*}
 */
export function openUrlBase(url, isOpenNew) {
  let a = document.createElement('a')
  a.setAttribute('href', url)
  if (isOpenNew) {
    a.setAttribute('target', '_blank')
  }
  a.setAttribute('id', 'd2admin-link-temp')
  document.body.appendChild(a)
  // a标签触发下载会自动读取文件名
  // error事件监听器
  a.addEventListener('error', handleDownloadError);
  // 不做处理
  a.click();
  document.body.removeChild(a)

  return
  // 添加请求头Authorization
  a.addEventListener('click', function () {
    // this.setRequestHeader('Authorization', 'Bearer ' + token);
    // 携带请求头
    // h5测试
    if (process.env.NODE_ENV == "development") {
      this.setRequestHeader(
        "Authorization",
        `Bearer ${process.env.VUE_APP_API_TOKEN}`
      );
      this.setRequestHeader(
        "X-Oars-Token",
        `${process.env.VUE_APP_API_TOKEN}`
      );
    } else {
      // 上线阶段,自动获取登录的 token localStorage Key:  IDAAS_BEARER_TOKEN
      let IDAAS_BEARER_TOKEN = localStorage.getItem("IDAAS_BEARER_TOKEN") || "111";
      if (IDAAS_BEARER_TOKEN) {
        xhr.setRequestHeader(
          "Authorization",
          `Bearer ${IDAAS_BEARER_TOKEN}`
        );
      }
    }
  });
  document.body.removeChild(a)
}
// 获取到下载失败的相关信息,并进行相应的处理
function handleDownloadError(event) {
  console.log('下载失败:', event);
  // 或者
  window.alert('下载失败,请重试!');
}