JavaScript无法直接读取自定义响应头,必须由服务端通过Access-Control-Expose-Headers显式声明(如X-Request-ID、X-Rate-Limit-Remaining),前端才能用response.headers.get()获取;注意逗号分隔无空格、大小写敏感,且预检请求OPTIONS也需包含该头。

JavaScript 中通过 fetch 或 XMLHttpRequest 发起请求时,服务器返回的自定义响应头(如 X-Request-ID、X-Rate-Limit-Remaining)默认**不会被浏览器暴露**给前端脚本,除非服务端明确在 Access-Control-Expose-Headers 响应头中声明。
确保服务端配置了 Access-Control-Expose-Headers
这是最关键的前置条件。如果后端没配,前端根本读不到自定义头。
- 例如,后端需返回类似:
Access-Control-Expose-Headers: X-Request-ID, X-Rate-Limit-Remaining, X-Total-Count - 只暴露你真正需要读取的头字段,不要写
*(CORS 规范中,通配符*不适用于带凭据的请求) - 若请求携带了
credentials: 'include',则Access-Control-Allow-Origin也不能为*,必须是具体域名
用 fetch 读取自定义响应头
fetch 的 Response.headers 是一个 Headers 对象,需用 .get()、.has() 等方法访问:
fetch('/api/data', {
method: 'GET',
credentials: 'include'
})
.then(response => {
// ✅ 只有在 expose 后才能读到
const requestId = response.headers.get('X-Request-ID');
const remaining = response.headers.get('X-Rate-Limit-Remaining');
if (requestId) {
console.log('请求ID:', requestId);
}
return response.json();
});
注意 XMLHttpRequest 的差异
XMLHttpRequest 同样受 Access-Control-Expose-Headers 限制,但读取方式略有不同:
立即学习“Java免费学习笔记(深入)”;
- 用
xhr.getResponseHeader('X-Request-ID')获取单个头 - 用
xhr.getAllResponseHeaders()获取所有暴露的响应头字符串(需手动解析) - 注意:调用
getResponseHeader必须在readyState === 4且status为成功状态之后
常见踩坑点
- 开发环境绕过 CORS? 浏览器插件或代理(如 vite 的 proxy)可能隐藏真实响应头,务必在真实跨域场景下验证
-
大小写敏感吗? HTTP 头名不区分大小写,但
get()方法传入的字符串建议按服务端实际发送的格式(通常首字母大写、其余小写) -
预检请求(OPTIONS)没返回 expose 头? 如果接口用了非简单请求(如带自定义 header),确保 OPTIONS 响应也包含正确的
Access-Control-Expose-Headers


















