nginx 返回405是因为未正确处理options预检请求,需在location块中显式拦截并返回204及cors头;关键在于add_header后必须return 204,且access-control-allow-origin与credentials不能共用通配符。

Nginx 返回 405 Not Allowed 给 OPTIONS 请求,本质是浏览器跨域预检被拦在了代理层——它根本没机会到达后端,更谈不上 CORS 响应。解决的关键不是“让后端处理”,而是在 Nginx 配置中主动拦截并正确响应 OPTIONS 请求。
明确识别 OPTIONS 请求是否被真正触发
打开浏览器 Network 面板,找到状态码为 405 的那条请求,点开 Headers → 查看 Request Method 是否为 OPTIONS。如果是,且紧随其后的真实请求(如 POST)呈灰色未发出,就确认是预检失败。
在 location 块中显式处理 OPTIONS
不要依赖后端,直接由 Nginx 短路响应预检。在对应接口的 location 块内添加:
- 检测请求方法为 OPTIONS
- 设置必要的 CORS 响应头
- 立即返回 204(No Content),不转发给后端
location /api/ {
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' 'Content-Type, Authorization, X-Requested-With';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
⚠️ 注意:
if在location内使用是安全的;但避免在server级别或嵌套复杂逻辑中滥用if。
避免常见陷阱
- 不要只写
add_header而忘记return 204—— 缺少return会导致 Nginx 继续执行后续指令(比如proxy_pass),而多数后端并不处理 OPTIONS,最终仍报 405。 -
Access-Control-Allow-Origin: *与Access-Control-Allow-Credentials: true不能共存;若需带 cookie,必须指定明确域名,如https://your-app.com。 -
Access-Control-Allow-Headers要覆盖前端实际发送的自定义头(如Authorization、X-Token),否则预检仍失败。
验证是否生效
用 curl 模拟预检请求:
curl -X OPTIONS http://your-domain.com/api/login \ -H "Origin: https://example.com" \ -H "Access-Control-Request-Method: POST" \ -H "Access-Control-Request-Headers: Content-Type, Authorization" \ -I
应看到状态码 204,且响应头中包含上述 Access-Control-* 字段。
不复杂但容易忽略











