最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Nginx跨域代理的完整排坑指南(從證書錯誤到CORS配置)

 更新時間:2026年04月09日 08:29:05   作者:碼上有潛  
本文詳細記錄了一個項目中使用Nginx作為反向代理解決跨域問題的過程,從為子域名申請獨立SSL證書、處理CORS預檢請求、避免add_header語法錯誤、正確設(shè)置代理Host頭、以及后端HTTPS證書問題等方面逐一排查并解決,最終得到正確的Nginx配置,需要的朋友可以參考下

一、背景與需求

最近在做一個項目,架構(gòu)如下:

  • 前端域名https://www.example.com
  • 第三方APIhttps://thirdparty-api.example.net(不支持 CORS)
  • 目標:前端需要調(diào)用該第三方 API,但存在跨域問題

解決方案:使用 Nginx 做反向代理,將請求轉(zhuǎn)發(fā)到自己的子域名 https://api.example.com,并在 Nginx 層添加 CORS 響應頭。

預期請求鏈路:

瀏覽器 → api.example.com (Nginx) → thirdparty-api.example.net

本以為是個簡單的配置,結(jié)果前后踩了 6 個坑,耗時整整一天。本文將完整記錄排坑過程,希望對遇到類似問題的朋友有所幫助。

二、踩坑全記錄

坑位1:SSL 證書域名不匹配

錯誤現(xiàn)象

ERR_CERT_COMMON_NAME_INVALID

原因分析
api.example.com 使用了 www.example.com 的 SSL 證書,導致瀏覽器校驗證書時發(fā)現(xiàn)域名不匹配。

解決方案
api.example.com 申請獨立的 SSL 證書:

certbot certonly --nginx -d api.example.com

教訓:每個子域名都需要自己的證書,或使用通配符證書 *.example.com

坑位2:CORS 預檢請求失敗

錯誤現(xiàn)象

Access to fetch at 'https://api.example.com/...' from origin 'https://www.example.com' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present

原因分析
瀏覽器在發(fā)送實際請求前,會先發(fā)送一個 OPTIONS 預檢請求。Nginx 沒有正確處理這個請求,也沒有返回必要的 CORS 響應頭。

解決方案
在 Nginx 配置中添加 CORS 頭和 OPTIONS 請求處理:

location / {
    # CORS 響應頭
    add_header 'Access-Control-Allow-Origin' 'https://www.example.com' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;
    
    # 處理預檢請求
    if ($request_method = 'OPTIONS') {
        add_header 'Content-Length' 0;
        add_header 'Content-Type' 'text/plain charset=utf-8';
        return 204;
    }
    
    # 代理配置...
}

坑位3:add_header 語法錯誤

錯誤現(xiàn)象

[emerg] "add_header" directive is not allowed here in /etc/nginx/conf.d/ssl.conf:47

原因分析
add_header 指令被放在了 Nginx 不允許的位置。這個指令只能出現(xiàn)在 http、server、location 塊中,不能隨意放置。

錯誤示例

server {
    # 正確位置
    add_header 'Header1' 'value1' always;
    
    location / {
        # 正確位置
        add_header 'Header2' 'value2' always;
    }
}

# ? 錯誤:在 server/location 塊外面
add_header 'Header3' 'value3' always;

解決方案
確保所有 add_header 都在 serverlocation 塊內(nèi)部。

坑位4:Access-Control-Allow-Origin 重復

錯誤現(xiàn)象

The 'Access-Control-Allow-Origin' header contains multiple values 
'https://www.example.com, https://www.example.com', but only one is allowed.

原因分析
Nginx 配置中 add_header 'Access-Control-Allow-Origin' ... 被寫了兩次,導致響應頭中出現(xiàn)重復值。

解決方案
檢查配置文件,確保每個 CORS 頭只添加一次。如果同時在 serverlocation 塊中添加了,保留一處即可。

坑位5:代理 Host 頭不正確

錯誤現(xiàn)象
后端 API 返回 502 或 404,但直接訪問后端 API 是正常的。

原因分析
默認情況下 proxy_set_header Host $host 會將 Host 頭設(shè)置為 api.example.com,而后端 API 可能期望的是自己的域名 thirdparty-api.example.net。

解決方案
使用 $proxy_host 變量,它保存的是 proxy_pass 中指定的域名:

# ? 錯誤:Host 頭變成 api.example.com
proxy_set_header Host $host;

# ? 正確:Host 頭保持 thirdparty-api.example.net
proxy_set_header Host $proxy_host;

坑位6:后端使用 HTTPS 導致證書問題

錯誤現(xiàn)象
Nginx 代理到 https://thirdparty-api.example.net 時出現(xiàn) SSL 錯誤。

原因分析
Nginx 作為代理去訪問 HTTPS 后端時,需要驗證后端證書。如果后端證書有問題(自簽名、過期、域名不匹配等),Nginx 會拒絕連接。

解決方案
有兩種方式:

方案A(推薦):使用 HTTP 協(xié)議代理

# 如果后端支持 HTTP,直接用 HTTP
proxy_pass http://thirdparty-api.example.net$request_uri;

方案B:忽略證書驗證(僅臨時使用)

proxy_pass https://thirdparty-api.example.net$request_uri;
proxy_ssl_verify off;  # 關(guān)閉證書驗證

三、最終正確的配置

經(jīng)過以上所有坑位的修復,最終配置如下:

server {
    listen 443 ssl;
    server_name api.example.com;
    # DNS 解析器(使用域名代理時推薦添加)
    resolver 114.114.114.114 223.5.5.5 valid=30s;
    resolver_timeout 10s;
    # SSL 證書(使用子域名自己的證書)
    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
    # HSTS 安全頭
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    # SSL 配置
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;
    client_max_body_size 100M;
    location / {
        # ========== CORS 配置 ==========
        add_header 'Access-Control-Allow-Origin' 'https://www.example.com' always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        # 處理預檢請求
        if ($request_method = 'OPTIONS') {
            add_header 'Content-Length' 0;
            add_header 'Content-Type' 'text/plain charset=utf-8';
            return 204;
        }
        # ========== 代理配置 ==========
        # 核心轉(zhuǎn)發(fā)(使用 HTTP 避免后端證書問題)
        proxy_pass http://thirdparty-api.example.net$request_uri;
        # 關(guān)鍵:使用 $proxy_host 保持原始 Host
        proxy_set_header Host $proxy_host;
        # 傳遞真實客戶端信息
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        # HTTP 1.1 支持
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        # 超時設(shè)置
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        # API 最佳實踐:禁用緩存
        proxy_buffering off;
        proxy_cache off;
    }
}
# HTTP 重定向到 HTTPS
server {
    listen 80;
    server_name api.example.com;
    return 301 https://$server_name$request_uri;
}

四、核心經(jīng)驗總結(jié)

1. 關(guān)于 SSL 證書

要點說明
子域名需要獨立證書api.example.com 不能使用 www.example.com 的證書
申請 命令certbot certonly --nginx -d api.example.com
通配符證書*.example.com 可以覆蓋所有子域名

2. 關(guān)于 CORS 配置

要點說明
必須處理 OPTIONS瀏覽器預檢請求需要返回 204
頭不能重復Access-Control-Allow-Origin 只能出現(xiàn)一次
位置限制add_header 只能在 server/location 塊內(nèi)

3. 關(guān)于代理轉(zhuǎn)發(fā)

要點說明
Host 頭用 $proxy_host保持后端期望的域名
添加 $request_uri完整傳遞請求路徑
后端可以用 HTTP瀏覽器到 Nginx 需要 HTTPS,Nginx 到后端可以用 HTTP

4. 調(diào)試技巧

# 測試 Nginx 配置語法
nginx -t

# 查看錯誤日志
tail -f /var/log/nginx/error.log

# 測試 CORS 響應頭
curl -X OPTIONS https://api.example.com/api/test \
  -H "Origin: https://www.example.com" \
  -H "Access-Control-Request-Method: POST" \
  -v 2>&1 | grep -i "access-control"

五、一個重要的認知

Postman 能請求成功 ≠ 瀏覽器能請求成功

工具是否檢查 CORS說明
Postman? 不檢查桌面應用,不受瀏覽器安全策略限制
curl? 不檢查命令行工具
瀏覽器? 嚴格檢查為了用戶安全,必須配置正確的 CORS

這個認知能幫助您在調(diào)試時快速定位問題:Postman 通但瀏覽器不通 → 99% 是 CORS 配置問題。

六、架構(gòu)總結(jié)

最終的成功架構(gòu):

瀏覽器 -----------(HTTPS)-----------> Nginx -----------(HTTP)-----------> 后端
(www.example.com)              (api.example.com)              (thirdparty-api)
         ↑                              ↑                              ↑
    安全連接                      SSL證書 + CORS頭                 內(nèi)部通信

關(guān)鍵設(shè)計思想

  • 瀏覽器到 Nginx:必須 HTTPS,證書有效
  • Nginx 到后端:可以用 HTTP,避免證書麻煩
  • Nginx 層統(tǒng)一處理 CORS,后端無需改造

七、寫在最后

這次排坑讓我深刻體會到:

  1. Nginx 配置順序和位置非常重要,一個小錯誤就能導致整個服務(wù)不可用
  2. CORS 不是后端的事,是 Nginx/網(wǎng)關(guān)層的事,統(tǒng)一處理比每個后端服務(wù)單獨配置要優(yōu)雅得多
  3. HTTPS 是端到端的,但中間代理可以用 HTTP 轉(zhuǎn)發(fā),不影響整體安全性
  4. 遇到問題先看日志,Nginx 的錯誤日志非常詳細,能定位 90% 的問題

以上就是Nginx跨域代理的完整排坑指南(從證書錯誤到CORS配置)的詳細內(nèi)容,更多關(guān)于Nginx跨域代理排坑指南的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解Nginx 虛擬主機配置的三種方式(基于IP)

    詳解Nginx 虛擬主機配置的三種方式(基于IP)

    Nginx配置虛擬主機支持3種方式主要有基于IP的虛擬主機配置,基于端口的虛擬主機配置,基于域名的虛擬主機配置。本文主要介紹了基于IP配置的實現(xiàn),感興趣的小伙伴們可以參考一下
    2018-10-10
  • 同一臺服務(wù)器安裝多個Nginx的方法總結(jié)

    同一臺服務(wù)器安裝多個Nginx的方法總結(jié)

    在同一臺服務(wù)器上安裝多個nginx完全沒有問題,但有些地方是需要注意的,這篇文章為大家整理了一些常會遇到的問題以及解決方法,需要的可以參考一下
    2023-08-08
  • 通過Nginx實現(xiàn)前端與后端的協(xié)同部署

    通過Nginx實現(xiàn)前端與后端的協(xié)同部署

    在現(xiàn)代 web 開發(fā)中,前端與后端的協(xié)同部署是一個關(guān)鍵問題,一個高效的部署策略不僅能提升用戶體驗,還能簡化開發(fā)流程,今天,我們就來探討如何利用 Nginx 實現(xiàn)前端與后端的協(xié)同部署,需要的朋友可以參考下
    2025-03-03
  • 利用Nginx代理如何解決前端跨域問題詳析

    利用Nginx代理如何解決前端跨域問題詳析

    這篇文章主要給大家介紹了關(guān)于利用Nginx代理如何解決前端跨域問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者使用Nginx具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-08-08
  • 詳解Nginx中HTTP的keepalive相關(guān)配置

    詳解Nginx中HTTP的keepalive相關(guān)配置

    這篇文章主要介紹了Nginx中HTTP的keepalive相關(guān)配置,以及Nginx的Httpd守護進程相關(guān)的keepalive timeout配置,需要的朋友可以參考下
    2016-01-01
  • nginx中用JSON格式記錄日志的配置示例

    nginx中用JSON格式記錄日志的配置示例

    這篇文章主要介紹了nginx中用JSON格式記錄日志的配置示例,其實就是定義一個JSON的日志格式,然后在需要的地方調(diào)用即可,需要的朋友可以參考下
    2014-07-07
  • Nginx訪問無權(quán)限的問題解決

    Nginx訪問無權(quán)限的問題解決

    Nginx啟動后訪問時服務(wù)器返回權(quán)限拒絕錯誤,原因是Nginx進程沒有訪問目標文件的權(quán)限,解決方法包括檢查和修復文件及目錄權(quán)限,下面就來詳細的介紹一下,感興趣的可以了解一下
    2026-03-03
  • WordPress與Drupal的Nginx配置rewrite重寫規(guī)則示例

    WordPress與Drupal的Nginx配置rewrite重寫規(guī)則示例

    這篇文章主要介紹了WordPress與Drupal的Nginx配置重寫規(guī)則示例,文中介紹的rewrite寫法簡單而突出配置重點,需要的朋友可以參考下
    2016-01-01
  • 利用nginx訪問日志如何記錄mysql中的用戶id詳解

    利用nginx訪問日志如何記錄mysql中的用戶id詳解

    這篇文章主要給大家介紹了關(guān)于利用nginx訪問日志如何記錄mysql中用戶id的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面跟著小編一起來學習學習吧。
    2017-07-07
  • nginx配置限制同一個ip的訪問頻率方法

    nginx配置限制同一個ip的訪問頻率方法

    今天小編就為大家分享一篇nginx配置限制同一個ip的訪問頻率方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08

最新評論

子洲县| 都江堰市| 新民市| 合水县| 清镇市| 山阴县| 鄂尔多斯市| 彰化县| 霞浦县| 合阳县| 冕宁县| 樟树市| 宁海县| 香港 | 石楼县| 大洼县| 博乐市| 阿尔山市| 西盟| 兰坪| 崇信县| 阳新县| 肇庆市| 开平市| 虞城县| 巨野县| 西丰县| 东方市| 松原市| 昭平县| 喀喇沁旗| 仁怀市| 德清县| 赫章县| 正蓝旗| 昌乐县| 亚东县| 河源市| 化州市| 赤水市| 沙雅县|