响应头设置 add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always; 是不是预检请求就会返回200了?
不一定。仅设置:
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
并不能保证预检请求(OPTIONS)会返回 200,原因如下:
❌ 问题核心:Nginx 默认不会处理 OPTIONS 请求
在 Nginx 中,如果你没有显式为 OPTIONS 请求配置一个能返回 200 状态码 的处理逻辑,那么:
- 即使你设置了
add_header ... always; - 如果后端(或 Nginx 配置)对
OPTIONS请求返回的是405 Method Not Allowed或404, - 那么浏览器收到的仍然是 非 200 响应,预检失败,实际请求被阻止。
💡
add_header ... always只是“如果响应被发送,就加上这个头”,但它不能改变响应状态码。
✅ 正确做法:显式处理 OPTIONS 请求并返回 200
你需要在 Nginx 配置中主动拦截 OPTIONS 请求,返回 200 + CORS 头:
location / {
# 处理预检请求
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Max-Age' 1728000; # 20天缓存预检
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204; # 或 return 200;
}
# 实际请求的 CORS 头(非预检)
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
# 你的代理或静态文件逻辑
proxy_pass http://backend;
}
🔔 推荐使用
return 204;(No Content),因为预检响应通常不需要 body。
📌 关键点总结
| 问题 | 说明 |
|---|---|
❌ 仅加 add_header |
不会改变 OPTIONS 请求的状态码(可能仍是 405) |
✅ 必须 return 200/204 |
显式返回成功状态,浏览器才认为预检通过 |
| ✅ 需包含必要 CORS 头 | Allow-Origin、Allow-Methods、Allow-Headers(如果前端用了自定义头) |
✅ 使用 if ($request_method = 'OPTIONS') |
在 Nginx 中拦截预检请求 |
🔍 如何验证?
用 curl 测试:
curl -H "Origin: https://example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Authorization" \
-X OPTIONS \
http://your-api.com/some-path
你应该看到:
- 状态码:
204或200 - 响应头包含:
Access-Control-Allow-Methods、Access-Control-Allow-Headers等
✅ 结论
只设置
add_header 'Access-Control-Allow-Methods' ... always;是不够的!
你必须显式处理OPTIONS请求并返回 200/204,否则预检会失败。
这是 Nginx 配置 CORS 时最常见的误区之一。

浙公网安备 33010602011771号