跨域预检请求失败问题分析

问题描述

浏览器发送 OPTIONS 预检请求后,Nginx 返回了 204 响应,且 Access-Control-Allow-Headers 设置为 *,但浏览器仍然报错:

1
2
3
Access to XMLHttpRequest at 'http://.../api/...'
from origin 'http://...' has been blocked by CORS policy:
Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

根因分析

W3C Fetch 规范限制

根据 W3C Fetch Standard 规范:

When credentials mode is “include”(即 Access-Control-Allow-Credentials: true),the following headers must NOT use wildcard *:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Headers
  • Access-Control-Allow-Methods

简而言之:Access-Control-Allow-Credentials: true 与通配符 * 互斥。

问题响应示例

1
2
3
Access-Control-Allow-Credentials: true    ← 要求明确列出允许的值
Access-Control-Allow-Headers: * ← 通配符,浏览器直接忽略并拒绝
Access-Control-Allow-Methods: * ← 同上

浏览器检测到 credentials 模式下 Allow-Headers*,认为这是一个无效的 CORS 响应,因此拦截了实际请求。

修复方案

将 Nginx 配置中的通配符替换为显式列举的值:

修改前

1
2
add_header Access-Control-Allow-Methods "*" always;
add_header Access-Control-Allow-Headers "*" always;

修改后

1
2
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS, PATCH, HEAD" always;
add_header Access-Control-Allow-Headers "content-type, authorization, x-requested-with, x-custom-header, accept, origin" always;

参考资料

跨域预检请求失败问题分析

https://www.imaegoo.com/2026/cors-issue-analysis/

作者

iMaeGoo

发布于

2026-08-19

更新于

2026-08-19

许可协议

CC BY 4.0

评论