Nginx反向代理后端接口解決跨域沖突、預檢報錯問題全流程
前言
日常開發(fā)部署后端服務時,常會遇到一個高頻難題:前端多域名訪問后端接口、Nginx 反向代理 + 后端自帶跨域配置,雙重沖突導致跨域報錯、OPTIONS 預檢請求失敗、接口請求異常。
前段時間部署項目,后端部署在本地127.0.0.1:8270,前端對接多個業(yè)務域名,包含test1.com、test2.com、test3.com等。
初期出現嚴重跨域問題:
- 后端自帶跨域響應頭,+ Nginx 額外配置跨域,出現重復跨域頭;
- 多域名訪問,跨域白域無法統(tǒng)一管理;
- 前端 OPTIONS 預檢請求無響應,接口直接攔截;
- 跨域證書、請求頭權限受限,POST、PUT 等請求報錯。
本文完整記錄,我如何通過 Nginx 配置優(yōu)化,一站式徹底解決多域名跨域、重復請求頭、預檢失敗全流程問題。
一、問題根源分析
1. 核心矛盾
后端服務本身配置了跨域響應頭,前端通過 Nginx 反向代理訪問,若 Nginx 再疊加跨域配置,會造成:
Access-Control-Allow-Origin重復報錯;- 多域名白名單無法統(tǒng)一管控;
- 瀏覽器跨域校驗規(guī)則沖突。
2. 特殊問題
現代前端請求中,POST、PUT、DELETE、帶Content-Type、Authorization請求頭的接口,會觸發(fā) OPTIONS 預檢請求。
3. 業(yè)務需求
項目需要支持多個前端域名訪問:
- test1.com
- test2.com
- test3.com
- 同時兼容 www 子域名訪問
二、解決方案整體思路
采用Nginx 全局接管跨域方案,核心思路四步走:
- 屏蔽后端跨域頭:禁止后端返回的跨域相關頭信息,避免重復沖突;
- 配置多域名白名單:正則匹配合法域名,動態(tài)配置跨域來源;
- 攔截 OPTIONS 預檢請求:Nginx 直接返回 204 狀態(tài)碼 + 標準跨域頭,不轉發(fā)后端;
- 常規(guī)請求統(tǒng)一附加跨域頭:所有正常接口請求,統(tǒng)一添加合規(guī)跨域配置。
全程不修改后端代碼,純 Nginx 配置優(yōu)化,零業(yè)務改動、低風險、一鍵生效。
三、分步落地配置優(yōu)化
第一步:屏蔽后端原生跨域響應頭
問題核心源頭就是「后端 + Nginx 雙重跨域」,優(yōu)先禁用后端所有跨域相關頭,杜絕沖突。
使用proxy_hide_header指令,屏蔽后端返回的跨域關鍵頭:
# 1. 先統(tǒng)一隱藏后端所有跨域頭(解決重復沖突問題) 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獲取訪問來源,通過正則匹配合法域名,動態(tài)賦值跨域來源,支持主域名 + www 子域名。
覆蓋當前所有業(yè)務域名:
- test1.com
- test2.com
- test3.com
# 2. 配置多域名白名單,動態(tài)匹配合法來源
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 前綴; - 僅匹配合法域名,非法來源不賦值,杜絕跨域漏洞;
- 動態(tài)賦值,符合瀏覽器跨域同源策略要求。
第三步:特殊處理 OPTIONS 預檢請求
前端復雜請求必先發(fā)送 OPTIONS 預檢,后端無對應處理邏輯,極易報錯。
解決方案:Nginx 直接攔截 OPTIONS 請求,返回 204 無內容狀態(tài)碼,并附加完整跨域頭,無需轉發(fā)后端:
# 3. 攔截OPTIONS預檢請求,直接返回204狀態(tài)碼
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/PUT/DELETE/OPTIONS;
- 放行常用請求頭:格式頭、授權頭;
- 開啟跨域憑證支持,適配登錄鑒權場景。
第四步:常規(guī)接口統(tǒng)一附加跨域頭
除預檢請求外,所有 GET、POST 等正常業(yè)務請求,統(tǒng)一添加跨域響應頭,保證接口正常訪問:
# 4. 正常業(yè)務請求,統(tǒng)一添加跨域配置 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關鍵字至關重要:無論響應狀態(tài)碼 200/400/500,都強制攜帶跨域頭,避免異常接口跨域失效。
第五步:保留原有反向代理核心配置
跨域配置完全獨立隔離,原有反向代理、IP 轉發(fā)、超時、WebSocket 升級等配置完全保留,不影響原有業(yè)務運行:
# 原有反向代理配置,完全保留無修改 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 配置
location / {
# 1. 先統(tǒng)一隱藏后端所有跨域頭(解決重復沖突問題)
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. 配置多域名白名單,動態(tài)匹配合法來源
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狀態(tài)碼
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. 正常業(yè)務請求,統(tǒng)一添加跨域配置
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
平滑重啟,不中斷線上業(yè)務。
以上就是Nginx反向代理后端接口解決跨域沖突、預檢報錯問題全流程的詳細內容,更多關于Nginx反向代理后端接口的資料請關注腳本之家其它相關文章!
相關文章
詳解Nginx的超時keeplive_timeout配置步驟
Nginx 處理的每個請求均有相應的超時設置,本文主要介紹了Nginx的超時keeplive_timeout配置步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05
Nginx 中 ssl_buffer_size 參數調優(yōu)的具體實現
ssl_buffer_size 不是越大越好,也不是越小越快,它本質是在首包響應速度和 TLS 協議開銷之間做取舍,本文主要介紹了Nginx 中 ssl_buffer_size 參數調優(yōu)的具體實現,感興趣的可以了解一下2026-04-04
Nginx配置動態(tài)代理后通過curl訪問報403問題
本文主要介紹了Nginx配置動態(tài)代理后通過curl訪問報403問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-06-06
nginx將https協議反向代理到http協議請求上的實現
本文主要介紹了nginx將https協議反向代理到http協議請求上的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-10-10

