You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过带自定义请求头的AJAX实现文件下载

完整AJAX实现带自定义请求头的文件下载方案

我懂你的需求——原来用window.open()能正常触发下载,但没法携带自定义请求头,所以得换AJAX方案。核心思路其实是用AJAX请求拿到文件的Blob数据,再通过前端创建临时下载链接来触发浏览器的下载行为,下面给你两种可行的完整实现:

方案一:使用Fetch API(推荐,更现代简洁)

async function downloadFileWithHeaders() {
  try {
    const downloadUrl = buildRequestUrl();
    // 发送带自定义头的请求
    const response = await fetch(downloadUrl, {
      method: 'GET', // 根据实际需求换成POST等其他方法
      headers: {
        'X-Custom-Token': 'your-auth-token',
        'X-User-Id': '12345'
        // 这里添加所有你需要的自定义请求头
      }
    });

    if (!response.ok) {
      throw new Error(`请求失败: ${response.status} ${response.statusText}`);
    }

    // 从响应头提取文件名(后端需返回Content-Disposition头)
    let fileName = 'downloaded-file';
    const contentDisposition = response.headers.get('Content-Disposition');
    if (contentDisposition) {
      const matches = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
      if (matches?.[1]) {
        fileName = decodeURIComponent(matches[1].replace(/['"]/g, ''));
      }
    }

    // 把响应转为Blob格式
    const blob = await response.blob();
    // 创建临时下载链接
    const url = window.URL.createObjectURL(blob);
    const downloadLink = document.createElement('a');
    downloadLink.href = url;
    downloadLink.download = fileName;
    document.body.appendChild(downloadLink);
    // 触发点击下载
    downloadLink.click();
    // 清理资源,避免内存泄漏
    window.URL.revokeObjectURL(url);
    document.body.removeChild(downloadLink);
  } catch (error) {
    console.error('下载出错:', error);
    alert('文件下载失败,请稍后重试');
  }
}

// 调用函数启动下载
downloadFileWithHeaders();

方案二:使用XMLHttpRequest(兼容旧浏览器)

function downloadFileWithHeadersXHR() {
  const downloadUrl = buildRequestUrl();
  const xhr = new XMLHttpRequest();
  xhr.open('GET', downloadUrl, true);
  
  // 添加自定义请求头
  xhr.setRequestHeader('X-Custom-Token', 'your-auth-token');
  xhr.setRequestHeader('X-User-Id', '12345');
  // 指定响应类型为Blob
  xhr.responseType = 'blob';

  xhr.onload = function() {
    if (xhr.status === 200) {
      // 提取文件名
      let fileName = 'downloaded-file';
      const contentDisposition = xhr.getResponseHeader('Content-Disposition');
      if (contentDisposition) {
        const matches = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
        if (matches?.[1]) {
          fileName = decodeURIComponent(matches[1].replace(/['"]/g, ''));
        }
      }

      const blob = xhr.response;
      const url = window.URL.createObjectURL(blob);
      const downloadLink = document.createElement('a');
      downloadLink.href = url;
      downloadLink.download = fileName;
      document.body.appendChild(downloadLink);
      downloadLink.click();
      // 清理资源
      window.URL.revokeObjectURL(url);
      document.body.removeChild(downloadLink);
    } else {
      console.error('请求失败,状态码:', xhr.status);
      alert('文件下载失败,请稍后重试');
    }
  };

  xhr.onerror = function() {
    console.error('网络请求出错');
    alert('文件下载失败,请检查网络连接');
  };

  xhr.send();
}

// 调用函数启动下载
downloadFileWithHeadersXHR();

关键注意事项:

  • CORS跨域问题:如果请求是跨域的,后端必须配置允许携带自定义请求头(在响应头中添加Access-Control-Allow-Headers: X-Custom-Token,X-User-Id),同时允许对应请求方法的跨域访问。
  • 后端响应配置:后端需要正确返回Content-Type(匹配文件类型,比如application/pdf、application/octet-stream),并且建议返回Content-Disposition头来指定文件名,这样前端能自动获取正确的文件名。
  • 资源清理:一定要调用window.URL.revokeObjectURL()释放Blob URL的资源,避免内存泄漏。

内容的提问来源于stack exchange,提问作者koryakinp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:29:31