14人参与 • 2026-04-29 • Mysql
日常开发部署后端服务时,常会遇到一个高频难题:前端多域名访问后端接口、nginx 反向代理 + 后端自带跨域配置,双重冲突导致跨域报错、options 预检请求失败、接口请求异常。
前段时间部署项目,后端部署在本地127.0.0.1:8270,前端对接多个业务域名,包含test1.com、test2.com、test3.com等。
初期出现严重跨域问题:
本文完整记录,我如何通过 nginx 配置优化,一站式彻底解决多域名跨域、重复请求头、预检失败全流程问题。
后端服务本身配置了跨域响应头,前端通过 nginx 反向代理访问,若 nginx 再叠加跨域配置,会造成:
access-control-allow-origin 重复报错;现代前端请求中,post、put、delete、带content-type、authorization请求头的接口,会触发 options 预检请求。
项目需要支持多个前端域名访问:
采用nginx 全局接管跨域方案,核心思路四步走:
全程不修改后端代码,纯 nginx 配置优化,零业务改动、低风险、一键生效。
问题核心源头就是「后端 + nginx 双重跨域」,优先禁用后端所有跨域相关头,杜绝冲突。
使用proxy_hide_header指令,屏蔽后端返回的跨域关键头:
# 1. 先统一隐藏后端所有跨域头(解决重复冲突问题) proxy_hide_header access-control-allow-origin; proxy_hide_header access-control-allow-methods; proxy_hide_header access-control-allow-headers; proxy_hide_header access-control-allow-credentials;
配置作用:后端无论如何配置跨域,都不会传递到前端,所有跨域逻辑全权交给 nginx 控制。
采用$http_origin获取访问来源,通过正则匹配合法域名,动态赋值跨域来源,支持主域名 + www 子域名。
覆盖当前所有业务域名:
# 2. 配置多域名白名单,动态匹配合法来源
set $cors_origin "";
if ($http_origin ~* "^https://(www\.)?test1\.com$") {
set $cors_origin $http_origin;
}
if ($http_origin ~* "^https://(www\.)?test2\.com$") {
set $cors_origin $http_origin;
}
if ($http_origin ~* "^https://(www\.)?test3\.com$") {
set $cors_origin $http_origin;
}
(www\.)?:兼容有无 www 前缀;前端复杂请求必先发送 options 预检,后端无对应处理逻辑,极易报错。
解决方案:nginx 直接拦截 options 请求,返回 204 无内容状态码,并附加完整跨域头,无需转发后端:
# 3. 拦截options预检请求,直接返回204状态码
if ($request_method = options) {
add_header access-control-allow-origin $cors_origin always;
add_header access-control-allow-methods "get,post,options,put,delete" always;
add_header access-control-allow-headers "content-type,authorization" always;
add_header access-control-allow-credentials "true" always;
return 204;
}
除预检请求外,所有 get、post 等正常业务请求,统一添加跨域响应头,保证接口正常访问:
# 4. 正常业务请求,统一添加跨域配置 add_header access-control-allow-origin $cors_origin always; add_header access-control-allow-methods "get,post,options,put,delete" always; add_header access-control-allow-headers "content-type,authorization" always; add_header access-control-allow-credentials "true" always;
always关键字至关重要:无论响应状态码 200/400/500,都强制携带跨域头,避免异常接口跨域失效。
跨域配置完全独立隔离,原有反向代理、ip 转发、超时、websocket 升级等配置完全保留,不影响原有业务运行:
# 原有反向代理配置,完全保留无修改 proxy_pass http://127.0.0.1:8270; proxy_set_header host $host; proxy_set_header x-real-ip $remote_addr; proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for; proxy_set_header remote-host $remote_addr; add_header x-cache $upstream_cache_status; proxy_set_header x-host $host:$server_port; proxy_set_header x-scheme $scheme; proxy_connect_timeout 30s; proxy_read_timeout 86400s; proxy_send_timeout 30s; proxy_http_version 1.1; proxy_set_header upgrade $http_upgrade; proxy_set_header connection "upgrade";
location / {
# 1. 先统一隐藏后端所有跨域头(解决重复冲突问题)
proxy_hide_header access-control-allow-origin;
proxy_hide_header access-control-allow-methods;
proxy_hide_header access-control-allow-headers;
proxy_hide_header access-control-allow-credentials;
# 2. 配置多域名白名单,动态匹配合法来源
set $cors_origin "";
if ($http_origin ~* "^https://(www\.)?test1\.com$") {
set $cors_origin $http_origin;
}
if ($http_origin ~* "^https://(www\.)?test2\.com$") {
set $cors_origin $http_origin;
}
if ($http_origin ~* "^https://(www\.)?test3\.com$") {
set $cors_origin $http_origin;
}
# 3. 拦截options预检请求,直接返回204状态码
if ($request_method = options) {
add_header access-control-allow-origin $cors_origin always;
add_header access-control-allow-methods "get,post,options,put,delete" always;
add_header access-control-allow-headers "content-type,authorization" always;
add_header access-control-allow-credentials "true" always;
return 204;
}
# 4. 正常业务请求,统一添加跨域配置
add_header access-control-allow-origin $cors_origin always;
add_header access-control-allow-methods "get,post,options,put,delete" always;
add_header access-control-allow-headers "content-type,authorization" always;
add_header access-control-allow-credentials "true" always;
# 原有反向代理核心配置,无任何修改
proxy_pass http://127.0.0.1:8270;
proxy_set_header host $host;
proxy_set_header x-real-ip $remote_addr;
proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
proxy_set_header remote-host $remote_addr;
add_header x-cache $upstream_cache_status;
proxy_set_header x-host $host:$server_port;
proxy_set_header x-scheme $scheme;
proxy_connect_timeout 30s;
proxy_read_timeout 86400s;
proxy_send_timeout 30s;
proxy_http_version 1.1;
proxy_set_header upgrade $http_upgrade;
proxy_set_header connection "upgrade";
}
校验 nginx 语法
nginx -t
若无报错,说明配置语法无误。
平滑重载生效
systemctl reload nginx
平滑重启,不中断线上业务。
以上就是nginx反向代理后端接口解决跨域冲突、预检报错问题全流程的详细内容,更多关于nginx反向代理后端接口的资料请关注代码网其它相关文章!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论