使用JS在下载文件时添加请求头header token信息

673 阅读2分钟

使用JS在下载文件时添加请求头header token信息

各位 JSer,在前端下载一个文件大家应该都不陌生吧,后端同事已经把文件准备好了,我们只需要调接口下载就好了。

通常,我们有一种最常见的方法:window.open(URL),在点击事件的回调里调用就好了,浏览器会为我们下载文件。但是这样存在一些场景无法适配,比如,请求的接口需要你传递 token 或别的认证信息,又或者你们的产品设计不允许在下载时闪现一个新页面。

如此,我们就需要使用 fetch 或者别的 axios 等等,结合 a 标签 来实现 模拟点击下载,这样可以在请求头 header 里带上 token,也不会闪现一个新页面。这里我们以 fetch 为例来实现:

  1. 首先使用 fetch 带上我们的 headers token 发起请求,
  2. 因为后端返回的是一个文件,我们使用 response.blob() 获取 Blob 对象
  3. 使用 response.headers.get('Content-Disposition')获取响应头里带的内容信息
  4. 使用 window.URL.createObjectURL(blob) window 下的方法创建指向这个内容的 URL,
  5. 接下来使用原生 JS 方法创建一个 a 标签,并设置 herf 为刚才的 URL
  6. 然后我们需要处理文件名,可以使用下面的正则来解析文件名,当然你也可以用自己的方法来解析,响应头的里的内容是可以看到的,你也可以 console 来看,通常后端返回的文件名是没有问题的,但是我们也需要处理一下,如果解析错误,有一个默认的文件名,你可以自己传入,没传入就是 file.txt
  7. 最后把这个 a 标签插入页面,再执行点击事件就能下载,要记得释放 window 下的这个 URL 对象哦。
export const downloadFileWithFetch = async (URL, token, fileName = 'file.txt') => {
  const response = await fetch(URL, {
    headers: {
      AccessToken: token,
    },
  });
  const blob = await response.blob(); // 获取Blob对象
  const contentDisposition = response.headers.get('Content-Disposition');//获取响应头
  const url = window.URL.createObjectURL(blob); // 创建一个指向该blob的URL
  const a = document.createElement('a');
  a.style.display = 'none';
  a.href = url;
  if (contentDisposition) {
    // 尝试从Content-Disposition解析文件名
    const matches = /"([^"]*)"/.exec(contentDisposition);
    if (matches != null && matches[1]) {
      a.download = matches[1];
    }else{
      a.download = fileName
    }
  }
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(url); // 释放URL对象
}