必须在 nginx 的 api location 块中通过 add_header access-control-expose-headers 显式声明需暴露的自定义响应头(如 x-request-id),并确保其作用于实际业务响应和 options 预检请求,且头名大小写、格式严格匹配后端返回值。

要在 Nginx 中让前端 JavaScript(如 fetch 或 XMLHttpRequest)成功读取自定义响应头(比如 X-Request-ID、X-RateLimit-Remaining),必须在服务端明确通过 Access-Control-Expose-Headers 响应头声明哪些自定义头可被暴露。仅设置 Access-Control-Allow-Origin 是不够的。
明确列出需要暴露的自定义响应头
浏览器默认只允许脚本访问简单的响应头(如 Cache-Control、Content-Language、Content-Type 等)。其他头必须显式声明。例如,若后端返回了 X-Trace-ID 和 X-Backend-Version,Nginx 配置中需写:
add_header Access-Control-Expose-Headers "X-Trace-ID, X-Backend-Version";
注意:
• 头名之间用英文逗号加空格分隔(推荐格式);
• 不要包含空格以外的多余字符(如中文逗号、引号嵌套错误);
• 大小写敏感,需与后端实际返回的头名完全一致(HTTP 头名通常规范为首字母大写驼峰)。
确保该指令作用于正确 location 块且不被覆盖
这个 add_header 必须出现在能匹配到实际 API 接口的 location 块中,且不能被子块中同名指令覆盖。常见错误是只在根 server 块或 OPTIONS 预检块里配置,而没在真正返回业务响应的 location 里设置。
推荐写法示例:
location /api/ {
proxy_pass http://backend;
add_header Access-Control-Allow-Origin "$http_origin";
add_header Access-Control-Expose-Headers "X-Request-ID, X-RateLimit-Reset";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
# 其他 proxy_* 配置...
}
配合预检请求(OPTIONS)正确响应
如果前端请求带了自定义请求头(如 Authorization)或非简单方法(如 PUT),浏览器会先发 OPTIONS 预检。此时 Nginx 需对 OPTIONS 请求也返回 Access-Control-Expose-Headers —— 否则预检失败,后续请求根本不会发出。
安全做法是:在处理 OPTIONS 的 location 块中同样添加该头,或统一在主 API location 中配置(Nginx 的 add_header 对所有响应生效,包括 204/200 OPTIONS 响应)。
无需单独为 OPTIONS 写 if ($request_method = 'OPTIONS') { ... },除非你用的是极老版本且无法继承 header。
验证是否生效
部署后,用浏览器开发者工具 → Network → 点击请求 → 查看 Response Headers,确认存在:
Access-Control-Expose-Headers: X-Request-ID, X-RateLimit-Reset- 且对应响应中确实含有这些自定义头(如
X-Request-ID: abc123) - 前端代码中可通过
response.headers.get('X-Request-ID')正常获取
若仍拿不到,检查是否缓存了旧响应(可加 add_header Cache-Control "no-cache"; 临时排除);或确认后端未覆盖 Nginx 设置的该 header(Nginx 默认会覆盖同名 header,但某些模块或 proxy_pass 场景下可能被后端重写)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











