如何在Nginx中添加请求头解决API调用时的CORS跨域错误?
解决Nginx下跨域CORS冲突问题
问题根源
你遇到的第二个错误是因为Access-Control-Allow-Origin头被重复设置:要么是你的API后端应用(比如PHP/Node.js/Python服务)已经返回了panel.example.ir这个值,同时Nginx又添加了*,导致响应头里出现两个值,违反CORS规则。
解决方案
方案1:检查并移除后端应用的CORS头
如果你的API后端代码中已经设置了Access-Control-Allow-Origin(比如硬编码为https://panel.example.ir),直接删除Nginx配置里的add_header Access-Control-Allow-Origin *;即可。
方案2:仅通过Nginx配置正确处理CORS
如果后端没有设置CORS头,按以下步骤配置Nginx的api.example.ir站点:
- 处理OPTIONS预请求:浏览器发起跨域复杂请求前会先发送OPTIONS预请求,需要单独返回CORS头并结束请求;
- 避免重复添加头:使用
always参数确保头在所有响应中都存在,同时精准指定允许的源(不要用*,如果你的请求带Cookie的话*会失效)。
具体配置示例:
server { listen 443 ssl; server_name api.example.ir; # 其他SSL、日志等原有配置... location / { # 动态匹配允许的跨域源 set $cors_origin ""; if ($http_origin ~* "^https://panel.example.ir$") { set $cors_origin $http_origin; } # 处理OPTIONS预请求 if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin $cors_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-Max-Age 3600; # 缓存预请求结果1小时 add_header Content-Length 0; add_header Content-Type text/plain; return 204; } # 为非OPTIONS请求添加CORS头 add_header Access-Control-Allow-Origin $cors_origin always; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always; add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With" always; # 原有后端代理配置 proxy_pass http://your_backend_server; # 替换成你的实际后端地址 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # ...其他代理配置 } }
关键注意事项
- 不要同时让后端和Nginx设置
Access-Control-Allow-Origin,选其中一处配置即可。 - 优先指定具体允许的源(比如
https://panel.example.ir)而非*,这样更安全,且支持带Cookie的跨域请求(需要同时在前端请求中设置withCredentials: true)。 - 使用
always参数确保CORS头在Nginx返回错误响应(比如404、500)时也能被添加。
内容的提问来源于stack exchange,提问作者محسن عباسی
相关产品推荐
相关产品推荐

