Nginx 配置跨域并不复杂,核心是设置正确的跨域响应头并正确处理 OPTIONS 预检请求,只要把握这两个关键点,就能优雅解决浏览器跨域报错,同时兼顾安全性和性能。
跨域现象与 Nginx 的作用
浏览器遵循同源策略,协议、域名、端口任一不同即为跨域,当前端页面请求后端 API 时,Nginx 作为反向代理,可以在响应阶段主动附加 Access-Control-Allow- 响应头,告诉浏览器“此次跨域请求是允许的”。
很多开发者误以为跨域必须由后端代码解决,Nginx 层就能直接处理,且能统一管理多套域名的策略,更方便。
基础跨域配置:三个核心响应头
最简单的配置,在需要跨域的 location 中添加以下内容:
location /api/ {
add_header Access-Control-Allow-Origin "$http_origin";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
}
Access-Control-Allow-Origin:指定允许的来源域名,用$http_origin动态反射当前请求来源,比写死 更安全。Access-Control-Allow-Methods:允许的 HTTP 方法,务必包含实际业务使用的方法。Access-Control-Allow-Headers:允许的自定义请求头,Content-Type、Authorization。
处理预检请求与携带凭证
当请求包含非简单头,或使用 PUT

、DELETE 等方法时,浏览器会先发送一个 OPTIONS 预检请求,很多跨域问题都源于预检请求未正确响应。
完整配置如下:
location /api/ {
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin "$http_origin";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
add_header Access-Control-Max-Age 86400;
return 204;
}
add_header Access-Control-Allow-Origin "$http_origin";
add_header Access-Control-Allow-Credentials true;
}
Access-Control-Max-Age:预检结果缓存时间,单位秒,可显著减少预检请求量,提升性能。Access-Control-Allow-Credentials true:允许携带 Cookie 或 HTTP 认证信息,注意此时不能使用 作为来源,必须明确指定域名。
需要强调的是,if 块内没有 return 会继续走后续逻辑,容易导致响应头重复,这里返回 204 状态码,代表预检成功且无响应体,语义准确。
更安全的多域名白名单方案
直接反射 $http_origin 虽然灵活,但任何域名都能通过请求拿到允许头,存在被恶意刷接口的风险。独立建议是:维护一份来源白名单,仅允许可信域名跨域。
map $http_origin $cors_origin {
default "";
"https://www.example.com" https://www.exam
ple.com;
"https://admin.example.com" https://admin.example.com;
}
server {
location /api/ {
if ($cors_origin != "") {
add_header Access-Control-Allow-Origin $cors_origin;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
}
if ($request_method = OPTIONS) {
return 204;
}
}
}
这种方案既满足了多域名支持,又避免了开放给所有站点,如果只需要一个来源,直接写死域名比反射更稳妥。
酷番云实践:云端防护与 Nginx 配置结合
我们在酷番云的实际运维中,曾遇到一个电商项目需要同时支持官网与小程序后台跨域,由于接口量大、域名分离,单纯在 Nginx 配置层容易漏改或冲突。
借助酷番云提供的 Nginx 托管配置中心,我们可以将跨域策略作为独立片段加载到对应 server 块中,并配合云端防火墙白名单,实现只允许指定域名访问 API 的细粒度控制,具体做法是:
- 在酷番云控制台维护跨域域名白名单,自动生成 Nginx 配置片段。
- 通过云端同步功能下发到多台 Nginx 节点,保证策略一致。
- 开启访问日志分析,实时监控跨域请求来源。
这样既保留了 Nginx 的高性能,又利用云平台统一管理,特别适合多域名、多环境团队的协作场景。
排查跨域问题的常见路径
很多配置看似正确,但仍报跨域,我建议按以下顺序排查:
- 确认浏览器实际收到的响应头

:通过 DevTools 的 Network 面板查看预检与正式请求的 response headers,确认
Access-Control-是否真实存在。 - 检查响应头是否被后端覆盖:Nginx 配置了
add_header,但上游应用也设置了同名响应头,需要清除后端无用的跨域逻辑。 - 确认
add_header所在层级生效:Nginx 的add_header会继承,但一旦内层重新定义了add_header,外层头会失效,建议统一放置在location内,确保不冲突。
相关问答
问:为什么我设置了 `Access-Control-Allow-Origin: `,携带 Cookie 的请求仍然失败?
答:因为浏览器规范规定, 不能与 Access-Control-Allow-Credentials: true 同时使用,两者共存时浏览器会直接拒绝请求,解决办法是明确指定来源域名,Access-Control-Allow-Origin: https://www.example.com,并同时设置 Access-Control-Allow-Credentials: true。
问:预检请求返回 204 后,浏览器依然提示跨域,可能是什么原因?
答:常见原因有三个:一是 Access-Control-Allow-Headers 中未包含请求头里的 Content-Type 或 Authorization;二是 Access-Control-Allow-Methods 缺少实际请求的方法;三是预检响应被 CDN 或网关缓存了过期的头信息,建议先检查预检响应头是否完整,再清理 CDN 缓存或调整 Nginx 层 add_header 配置。
如果你在 Nginx 跨域配置中遇到过其他诡异问题,欢迎在评论区留言,一起交流解决方案。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/765797.html

