带Authorization头的跨域请求需满足四项CORS硬性条件:①Access-Control-Allow-Headers必须显式包含Authorization;②Access-Control-Allow-Origin不能为*,须动态匹配可信源;③预检响应必须加always关键字返回全部CORS头;④Access-Control-Allow-Credentials必须同时出现在预检和实际响应中。

当前端发起带 Authorization 请求头的跨域请求时,浏览器会将其视为非简单请求,触发预检(OPTIONS)流程,并要求后端(或代理层如 Nginx)提供明确、合规的 CORS 响应头。配置稍有偏差就会导致请求被静默拦截——前端报错、控制台看不到响应体、后端日志却显示成功,这是最典型的排查盲区。
关键点在于:Authorization 头的存在,直接抬高了 CORS 校验门槛,必须同时满足四项硬性条件,缺一不可。
必须设置 Access-Control-Allow-Headers 包含 Authorization
浏览器在预检阶段会检查 Access-Control-Allow-Headers 是否明确列出 Authorization。如果没写,或只写了 *(通配符在含凭证时无效),预检失败,后续请求根本不会发出。
正确写法(注意大小写不敏感,但建议统一小写):
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With' always;
⚠️ 不要写成 Access-Control-Allow-Headers: * —— 当请求含 Authorization 或 Cookie 时,该通配符被浏览器忽略。
Access-Control-Allow-Origin 不能为 *,且必须精确匹配来源
只要请求带 Authorization(或 credentials: true),Access-Control-Allow-Origin 就*绝不允许设为 ``**。否则浏览器直接拒绝暴露响应。
你需要动态匹配可信源,例如:
map $http_origin $cors_origin {
default "";
"~^https?://(app|dashboard)\.company\.com$" "$http_origin";
"~^https?://localhost:3000$" "$http_origin";
}然后在 location 中使用:
立即学习“前端免费学习笔记(深入)”;
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
add_header 'Access-Control-Allow-Origin' $cors_origin always; add_header 'Access-Control-Allow-Credentials' 'true' always;
✅ 只有 $cors_origin 非空时才生效,避免对非法来源透出 Origin 头。
预检响应(OPTIONS)必须完整返回所有必要头,且加 always
if ($request_method = 'OPTIONS') { return 204; } 本身不触发默认 add_header(仅对 2xx/3xx 生效),所以所有 CORS 头都必须显式加 always:
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $cors_origin always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Max-Age' 1728000 always;
add_header 'Content-Length' 0 always;
return 204;
}? always 是线上最常遗漏的关键字,不加就等于没配。
不要在预检响应里传 Access-Control-Allow-Credentials?不,它必须出现
有些资料误称“预检响应不该带 Access-Control-Allow-Credentials”,这是错误的。W3C 规范明确要求:只要正式请求需要凭证,预检响应就必须包含该头,否则浏览器拒绝发起后续请求。
所以 add_header 'Access-Control-Allow-Credentials' 'true' always; 要同时出现在预检和实际响应中。
不复杂但容易忽略。

















