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

如何在React JS中获取Content-Disposition值并提取文件名

从下载API的Content-Disposition响应头提取文件名失败的解决方案

核心问题分析

你遇到的问题大概率是以下两个原因之一:

  • 跨域时响应头未暴露:如果前端和API服务器不在同一域名下,浏览器默认会限制前端读取Content-Disposition这类非CORS安全响应头,除非服务器配置了Access-Control-Expose-Headers明确允许访问该字段。
  • 代码逻辑疏漏:比如传递给提取方法的不是完整的Response对象,或者正则表达式无法匹配带引号的文件名格式。

分步解决方案

1. 服务器端配置(跨域场景必做)

如果是跨域请求,需要在API服务器的响应头中添加:

Access-Control-Expose-Headers: Content-Disposition

只有这样,浏览器才会允许前端代码读取这个响应头字段。

2. 修正文件名提取的正则表达式

Postman返回的Content-Disposition通常带引号(比如attachment; filename="invoice.pdf"),原正则无法匹配这种格式,调整后兼容带引号/不带引号的情况:

const getFilenameFromContentDisposition = (response: Response) => {
  const contentDisposition = response.headers.get("Content-Disposition");
  if (contentDisposition) {
    // 匹配两种格式:filename="xxx.pdf" 或 filename=xxx.pdf
    const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(contentDisposition);
    if (matches && matches[1]) {
      let filename = matches[1].trim();
      // 去除首尾引号(如果有)
      if (filename.startsWith('"') && filename.endsWith('"')) {
        filename = filename.slice(1, -1);
      }
      return filename;
    }
  }
  return "downloaded-file.pdf";
};

3. 传递完整的Response对象到下载方法

DownloadFile方法需要接收完整的fetch响应对象,而非响应体内容,完整调用流程如下:

// 触发下载的函数
const handleDownload = async () => {
  try {
    const response = await fetch('https://localhost/api/v2/fax/download/10019400/9cb9c99f-0d57-46b9-925a-8df05afa1d75');
    if (!response.ok) throw new Error('下载请求失败');
    DownloadFile(response);
  } catch (error) {
    console.error('下载出错:', error);
  }
};

export const DownloadFile = (response: Response) => {
  const filename = getFilenameFromContentDisposition(response);
  // 从响应中获取正确的blob对象
  response.blob().then(blob => {
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = filename;
    a.style.display = "none";
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    // 释放URL对象,避免内存泄漏
    URL.revokeObjectURL(url);
  });
};

4. 调试技巧

如果仍无法获取头信息,可打印所有可访问的响应头确认:

const response = await fetch('你的API地址');
console.log('可访问的响应头:', [...response.headers.keys()]);

如果输出里没有Content-Disposition,说明服务器未配置Access-Control-Expose-Headers,需要后端配合调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:43:13