直接在Nginx中拦截OPTIONS请求并返回204及完整CORS头可解决跨域预检失败;因浏览器对非简单请求先发OPTIONS预检,若后端未处理则返回404/405导致失败。

直接在 Nginx 配置中拦截并响应 OPTIONS 请求,不转发给后端,同时设置正确的 CORS 响应头,就能彻底解决浏览器发起跨域请求时的预检失败问题。
为什么需要单独处理 OPTIONS 请求
当前端发起带自定义 header(如 Authorization)、非简单方法(如 PATCH/PUT)或非简单 content-type(如 application/json)的请求时,浏览器会先发一个 OPTIONS 预检请求。如果 Nginx 没有明确响应它,而是直接透传给后端,而后端又没实现 OPTIONS 处理逻辑,就会返回 404 或 405,导致跨域失败。
在 location 块中显式拦截 OPTIONS
在对应 API 的 location 块内添加条件判断,对 OPTIONS 方法直接返回 204,并带上必要 CORS 头:
location /api/ {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "https://www.php.cn/link/ab3e363159c8a7f02c774f0d6bc7c922";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PATCH, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization";
add_header Access-Control-Allow-Credentials "true";
add_header Access-Control-Max-Age 1728000;
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
<pre class="brush:php;toolbar:false;">proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 其他 proxy 设置...
}
关键响应头说明与注意事项
-
Access-Control-Allow-Origin:不能用
*和Access-Control-Allow-Credentials: true同时出现;若需带 cookie,必须写明确域名 -
Access-Control-Allow-Headers:要包含前端实际发送的所有自定义 header,比如
Authorization、X-Request-ID -
Access-Control-Allow-Credentials:前端
fetch(..., { credentials: 'include' })时必须为true,且 Origin 不能是通配符 -
add_header 不在 if 中继承:Nginx 的
add_header在if块里不会自动继承外层配置,所有 CORS 头必须在 if 内完整写出
更简洁可靠的写法(推荐)
用 map 提前定义变量,避免重复写 header,也更易维护:
map $request_method $cors_method {
OPTIONS 1;
default 0;
}
<p>server {
location /api/ {
if ($cors_method) {
add_header Access-Control-Allow-Origin "<a href="https://www.php.cn/link/ab3e363159c8a7f02c774f0d6bc7c922">https://www.php.cn/link/ab3e363159c8a7f02c774f0d6bc7c922</a>";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, PATCH, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization";
add_header Access-Control-Allow-Credentials "true";
add_header Access-Control-Max-Age 1728000;
add_header Content-Length 0;
return 204;
}</p><pre class="brush:php;toolbar:false;"> proxy_pass http://backend;
# 其他 proxy 设置...
}
}
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











