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

Nginx解決Access-Control-Allow-Origin跨域問題完全指南

 更新時間:2026年03月21日 11:26:41   作者:Getgit  
跨域問題是由于瀏覽器的同源策略(Same-Origin Policy)限制導致的,本文給大家介紹Nginx解決Access-Control-Allow-Origin跨域問題完全指南,感興趣的朋友跟隨小編一起看看吧

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔

一、跨域問題概述

1.1 什么是跨域問題?

跨域問題是由于瀏覽器的同源策略(Same-Origin Policy)限制導致的。當A服務器的前端頁面嘗試訪問B服務器的API時,瀏覽器會阻止這種跨域請求。

同源策略要求:

  • 協議相同(http/https)
  • 域名相同
  • 端口相同

只要其中一項不同,即為跨域請求。

二、Nginx解決方案詳解

2.1 完整的Nginx配置示例

# nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
    worker_connections 1024;
}
http {
    # 包含MIME類型定義
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    # 日志格式
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main;
    # 基本優(yōu)化設置
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # Gzip壓縮
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    # 主服務器配置
    server {
        listen 9800;
        server_name localhost;
        root /usr/share/nginx/html;
        # 默認首頁
        index index.html index.htm;
        # ========== CORS跨域配置 ==========
        # 處理OPTIONS預檢請求
        location / {
            # 如果是OPTIONS請求,直接返回204
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' $http_origin;
                add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
                add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, X-Requested-With, X-Auth-Token, X-CSRF-Token, X-API-Key';
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain; charset=utf-8';
                add_header 'Content-Length' 0;
                return 204;
            }
            # 非OPTIONS請求,添加CORS頭部
            add_header 'Access-Control-Allow-Origin' $http_origin;
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
            add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, X-Requested-With, X-Auth-Token, X-CSRF-Token, X-API-Key';
            add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range';
            # 如果是前端靜態(tài)文件,直接返回
            try_files $uri $uri/ /index.html;
        }
        # ========== 反向代理配置(代理B服務器API) ==========
        # 方式1:通用API代理(推薦)
        location ~ ^/api/(.*)$ {
            proxy_pass http://192.168.X.XXX:9830/$1$is_args$args;
            proxy_redirect off;
            # 代理設置
            proxy_set_header Host $http_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;
            proxy_set_header X-Forwarded-Host $server_name;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            # 超時設置
            proxy_connect_timeout 60s;
            proxy_send_timeout 60s;
            proxy_read_timeout 60s;
            # 緩沖區(qū)設置
            proxy_buffer_size 128k;
            proxy_buffers 4 256k;
            proxy_busy_buffers_size 256k;
            # CORS頭部(只在響應時添加)
            add_header 'Access-Control-Allow-Origin' $http_origin always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH' always;
            add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, X-Requested-With, X-Auth-Token, X-CSRF-Token, X-API-Key' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range' always;
            # 處理OPTIONS預檢請求
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' $http_origin;
                add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
                add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, X-Requested-With, X-Auth-Token, X-CSRF-Token, X-API-Key';
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain; charset=utf-8';
                add_header 'Content-Length' 0;
                return 204;
            }
        }
        # 方式2:特定路徑代理(原示例中的配置)
        location ~ /quartz/ {
            proxy_pass http://192.168.X.XXX:9830;
            proxy_read_timeout 360s;
            proxy_send_timeout 360s;
            # 代理頭部
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $server_name;
            # CORS頭部配置
            add_header Front-End-Https on;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH' always;
            add_header 'Access-Control-Allow-Origin' $http_origin always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Access-Control-Allow-Headers' 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Mx-ReqToken, X-Requested-With, X-Auth-Token, X-CSRF-Token, X-API-Key' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range, X-Total-Count' always;
            # 緩存預檢請求
            add_header 'Access-Control-Max-Age' 1728000;
        }
        # 錯誤頁面配置
        error_page 404 /404.html;
        location = /404.html {
            root /usr/share/nginx/html;
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /usr/share/nginx/html;
        }
    }
    # ========== 多個后端服務配置示例 ==========
    server {
        listen 9801;
        server_name api-proxy.example.com;
        # 代理多個后端服務
        location /service1/ {
            proxy_pass http://backend1:8080/;
            # ... CORS配置同上
        }
        location /service2/ {
            proxy_pass http://backend2:8081/;
            # ... CORS配置同上
        }
    }
}

2.2 配置詳解

2.2.1 核心CORS頭部說明

# 允許的源(域名)
add_header 'Access-Control-Allow-Origin' $http_origin;
# 允許的HTTP方法
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
# 允許的請求頭
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, X-Requested-With';
# 是否允許發(fā)送Cookie
add_header 'Access-Control-Allow-Credentials' 'true';
# 預檢請求緩存時間(秒)
add_header 'Access-Control-Max-Age' 1728000;
# 暴露給客戶端的響應頭
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range';

2.2.2 變量說明

變量說明示例值
$http_origin請求頭中的Origin字段http://localhost:8080
$request_method請求方法GET, POST, OPTIONS
$http_host請求的Host頭example.com:9800
$remote_addr客戶端IP地址192.168.1.100
$scheme請求協議http, https

三、不同場景的配置方案

3.1 場景1:開發(fā)環(huán)境(允許所有源)

# 開發(fā)環(huán)境配置 - 允許所有來源
map $http_origin $cors_origin {
    default "*";
}
server {
    listen 9800;
    location /api/ {
        # 開發(fā)環(huán)境:允許所有來源
        add_header 'Access-Control-Allow-Origin' $cors_origin;
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' '*';
        add_header 'Access-Control-Allow-Headers' '*';
        # 處理OPTIONS請求
        if ($request_method = 'OPTIONS') {
            return 204;
        }
        proxy_pass http://backend:8080;
    }
}

3.2 場景2:生產環(huán)境(白名單限制)

# 生產環(huán)境配置 - 白名單控制
map $http_origin $cors_origin {
    # 默認不允許
    default "";
    # 允許的域名
    ~^https?://(www\.)?example\.com(:[0-9]+)?$ $http_origin;
    ~^https?://api\.example\.com(:[0-9]+)?$ $http_origin;
    ~^https?://localhost(:[0-9]+)?$ $http_origin;
    ~^https?://127\.0\.0\.1(:[0-9]+)?$ $http_origin;
}
server {
    listen 9800;
    location /api/ {
        # 只有在白名單內才添加CORS頭部
        if ($cors_origin != "") {
            add_header 'Access-Control-Allow-Origin' $cors_origin;
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, X-Requested-With';
        }
        # 處理OPTIONS請求
        if ($request_method = 'OPTIONS') {
            if ($cors_origin != "") {
                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' 'Authorization, Content-Type, Accept, X-Requested-With';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Length' 0;
                return 204;
            }
        }
        proxy_pass http://backend:8080;
    }
}

3.3 場景3:微服務架構

# 微服務網關配置
upstream auth_service {
    server auth-service:8081;
}
upstream order_service {
    server order-service:8082;
}
upstream product_service {
    server product-service:8083;
}
server {
    listen 9800;
    # 認證服務
    location /auth/ {
        proxy_pass http://auth_service/;
        include /etc/nginx/conf.d/cors.conf;
    }
    # 訂單服務
    location /orders/ {
        proxy_pass http://order_service/;
        include /etc/nginx/conf.d/cors.conf;
    }
    # 商品服務
    location /products/ {
        proxy_pass http://product_service/;
        include /etc/nginx/conf.d/cors.conf;
    }
}
# cors.conf - 統(tǒng)一的CORS配置
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, X-Requested-With, X-Auth-Token';
add_header 'Access-Control-Expose-Headers' 'Content-Length, Content-Range, X-Total-Count';
if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Origin' $http_origin;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
    add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, X-Requested-With, X-Auth-Token';
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Length' 0;
    return 204;
}

四、常見問題與解決方案

4.1 問題1:add_header不生效

原因: Nginx的add_header指令在錯誤頁面或某些條件下可能不生效。

解決方案: 使用always參數

# 使用always確保頭部始終添加
add_header 'Access-Control-Allow-Origin' $http_origin always;
add_header 'Access-Control-Allow-Credentials' 'true' always;

4.2 問題2:攜帶Cookie時跨域失敗

原因: 當使用Access-Control-Allow-Credentials: true時,不能使用通配符*作為源。

解決方案: 動態(tài)設置允許的源

# 動態(tài)獲取請求的Origin
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
# 或者使用條件判斷
if ($http_origin ~* (example\.com|localhost)) {
    add_header 'Access-Control-Allow-Origin' $http_origin;
    add_header 'Access-Control-Allow-Credentials' 'true';
}

4.3 問題3:OPTIONS預檢請求返回404

原因: 后端服務沒有處理OPTIONS請求。

解決方案: 在Nginx層面處理OPTIONS請求

location /api/ {
    # 單獨處理OPTIONS請求
    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' 'Authorization, Content-Type, Accept';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Length' 0;
        return 204;
    }
    # 正常請求轉發(fā)
    proxy_pass http://backend:8080;
}

4.4 問題4:WebSocket跨域問題

解決方案: 特殊處理WebSocket連接

location /ws/ {
    proxy_pass http://backend:8080;
    proxy_http_version 1.1;
    # WebSocket升級
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    # CORS配置
    add_header 'Access-Control-Allow-Origin' $http_origin;
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Authorization, Upgrade, Connection';
}

五、測試與驗證

5.1 測試腳本

// test-cors.html
<!DOCTYPE html>
<html>
<head>
    <title>CORS測試</title>
</head>
<body>
    <h1>CORS測試頁面</h1>
    <button onclick="testCORS()">測試跨域請求</button>
    <div id="result"></div>
    <script>
        async function testCORS() {
            try {
                const response = await fetch('http://A服務器IP:9800/api/test', {
                    method: 'GET',
                    credentials: 'include', // 攜帶Cookie
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': 'Bearer test-token'
                    }
                });
                const data = await response.json();
                document.getElementById('result').innerHTML = 
                    `<pre>成功: ${JSON.stringify(data, null, 2)}</pre>`;
            } catch (error) {
                document.getElementById('result').innerHTML = 
                    `<pre style="color:red">錯誤: ${error.message}</pre>`;
            }
        }
        // 預檢請求測試
        async function testPreflight() {
            try {
                const response = await fetch('http://A服務器IP:9800/api/test', {
                    method: 'PUT',
                    credentials: 'include',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-Custom-Header': 'custom-value'
                    },
                    body: JSON.stringify({ test: 'data' })
                });
                const data = await response.json();
                console.log('預檢請求成功:', data);
            } catch (error) {
                console.error('預檢請求失敗:', error);
            }
        }
    </script>
</body>
</html>

5.2 使用curl測試

# 測試OPTIONS預檢請求
curl -X OPTIONS http://A服務器IP:9800/api/test \
  -H "Origin: http://localhost:8080" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: authorization,content-type" \
  -v
# 測試正常請求
curl -X GET http://A服務器IP:9800/api/test \
  -H "Origin: http://localhost:8080" \
  -H "Authorization: Bearer test-token" \
  -v

5.3 Nginx配置檢查

# 檢查nginx配置語法
nginx -t
# 重新加載配置(不重啟)
nginx -s reload
# 查看nginx錯誤日志
tail -f /var/log/nginx/error.log
# 查看訪問日志
tail -f /var/log/nginx/access.log

六、安全注意事項

6.1 安全建議

  1. 不要使用通配符*:在生產環(huán)境中,應明確指定允許的域名
  2. 限制允許的方法:只開放必要的HTTP方法
  3. 限制允許的頭部:只允許必要的請求頭
  4. 設置合理的緩存時間Access-Control-Max-Age不宜設置過長
  5. 使用HTTPS:跨域請求應使用HTTPS加密傳輸

6.2 安全配置示例

# 安全增強的CORS配置
map $http_origin $allowed_origin {
    # 明確允許的域名列表
    "https://www.example.com" "https://www.example.com";
    "https://api.example.com" "https://api.example.com";
    "https://staging.example.com" "https://staging.example.com";
    default "";
}
server {
    # ... 其他配置 ...
    location /api/ {
        # 僅對允許的源添加CORS頭部
        if ($allowed_origin != "") {
            add_header 'Access-Control-Allow-Origin' $allowed_origin;
            add_header 'Access-Control-Allow-Credentials' 'true';
            add_header 'Access-Control-Allow-Methods' 'GET, POST';
            add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
            add_header 'Access-Control-Expose-Headers' 'X-RateLimit-Limit, X-RateLimit-Remaining';
            add_header 'Access-Control-Max-Age' 86400; # 24小時
        }
        # 安全相關的其他頭部
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-XSS-Protection "1; mode=block" always;
        proxy_pass http://backend:8080;
    }
}

七、總結

通過Nginx配置解決跨域問題是最常用且有效的方法之一。關鍵點總結:

  • 核心原理:通過反向代理和添加CORS響應頭解決跨域
  • 必須頭部
    • Access-Control-Allow-Origin
    • Access-Control-Allow-Methods
    • Access-Control-Allow-Headers
    • Access-Control-Allow-Credentials(需要時)
  • 處理流程
    • 瀏覽器發(fā)送OPTIONS預檢請求
    • Nginx直接響應或轉發(fā)到后端
    • 添加必要的CORS頭部
    • 允許實際請求通過
  • 最佳實踐
    • 開發(fā)環(huán)境可以寬松配置
    • 生產環(huán)境需要嚴格的白名單控制
    • 結合HTTPS提升安全性
    • 定期審查和更新配置

通過合理配置Nginx,不僅可以解決跨域問題,還能提升系統(tǒng)的安全性、性能和可維護性。

到此這篇關于Nginx解決Access-Control-Allow-Origin跨域問題完全指南的文章就介紹到這了,更多相關Nginx Access-Control-Allow-Origin跨域內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Crontab+Shell做Nginx日志切割腳本實例代碼

    Crontab+Shell做Nginx日志切割腳本實例代碼

    本篇文章主要介紹了Crontab+Shell做Nginx日志切割腳本實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • Nginx實現防盜鏈的多種方式

    Nginx實現防盜鏈的多種方式

    防盜鏈指的是防止其他網站未經許可直接引用你的資源(如圖片、音視頻文件、文檔等),這樣做不僅能有效節(jié)約帶寬,還能防止未經授權的內容被濫用,本文給大家介紹了Nginx實現防盜鏈的多種方式,需要的朋友可以參考下
    2025-01-01
  • Nginx設置HTTPS的方法步驟

    Nginx設置HTTPS的方法步驟

    本文主要介紹了NGINX設置HTTPS的方法步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Nginx的信號控制

    Nginx的信號控制

    今天小編就為大家分享一篇關于Nginx的信號控制,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Nginx配置WebSocket反向代理的實現示例

    Nginx配置WebSocket反向代理的實現示例

    本文主要介紹了Nginx配置WebSocket反向代理的實現示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-08-08
  • Nginx配置多個端口進行監(jiān)聽的實現

    Nginx配置多個端口進行監(jiān)聽的實現

    隨著容器的應用越來越多,將nginx部署在容器中也是常有之事,本文主要介紹了Nginx配置多個端口進行監(jiān)聽的實現,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-07-07
  • Windows安裝nginx1.10.1反向代理訪問IIS網站

    Windows安裝nginx1.10.1反向代理訪問IIS網站

    這篇文章主要為大家詳細介紹了Windows安裝nginx1.10.1反向代理訪問IIS網站的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • nginx?某些url只能由特定ip訪問的實現

    nginx?某些url只能由特定ip訪問的實現

    在Nginx中針對某些URL只允許特定IP地址訪問,本文就來介紹一下如何實現,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • nginx源碼之epoll事件循環(huán)處理方式

    nginx源碼之epoll事件循環(huán)處理方式

    這篇文章主要介紹了nginx源碼之epoll事件循環(huán)處理方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-07-07
  • nginx安裝圖解_動力節(jié)點Java學院整理

    nginx安裝圖解_動力節(jié)點Java學院整理

    這篇文章主要為大家詳細介紹了nginx安裝的圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08

最新評論

江都市| 瓮安县| 漾濞| 浠水县| 沂水县| 鄯善县| 阿鲁科尔沁旗| 秦安县| 山阴县| 澳门| 南木林县| 霸州市| 宝清县| 泾源县| 汶川县| 灵川县| 丹巴县| 顺昌县| 霸州市| 宁陕县| 普宁市| 安吉县| 彰化县| 徐闻县| 哈尔滨市| 金秀| 炎陵县| 台湾省| 湖口县| 屏东县| 林口县| 禄丰县| 鸡西市| 无棣县| 道孚县| 赤城县| 青州市| 阿图什市| 浏阳市| 南木林县| 武川县|