Nginx解决跨域问题

原理:在 B 服务的 API 服务器端设置响应头,允许来自 A 域名的跨域请求

# 强制 HTTP 跳转到 HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;  # 301 永久重定向
}

# 定义允许的域名列表a.com www.a.com
map $http_origin $allow_origin {
        default "";
        ~^https?://(a\.com|www\.a\.com) $http_origin;
}


server {
        listen 443 ssl;
        access_log on;
        server_name b.com www.b.com;

        access_log /var/log/nginx/b.access.log;
        error_log /var/log/nginx/b.error.log;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers off;
        ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
        resolver 1.1.1.1 8.8.4.4 8.8.8.8 valid=300s;
        resolver_timeout 10s;
        ssl_session_cache shared:SSL:32m;
        ssl_session_timeout 10m;

        ssl_certificate /etc/letsencrypt/archive/b.com/fullchain1.pem;
        ssl_certificate_key /etc/letsencrypt/archive/b.com/privkey1.pem;

        location / {
                proxy_pass http://127.0.0.1:5000;  # 后端服务地址
                proxy_set_header Connection $http_connection;
                proxy_set_header Upgrade $http_upgrade;

                proxy_set_header Host $host;        # 传递原始域名[2,7](@ref)
                proxy_set_header X-Real-IP $remote_addr;  # 获取真实客户端IP[2,4](@ref)
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;




                #处理跨域请求
                add_header 'Access-Control-Allow-Origin' $allow_origin 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;

                # 处理预检请求(OPTIONS)
                if ($request_method = 'OPTIONS') {
                        return 204;
                }
        }

}

注意事项: 不要将 Access-Control-Allow-Origin 设为 *(除非是公共 API),否则可能引发安全问题。 如果请求携带 Cookie 或 Token,需设置 Access-Control-Allow-Credentials: true,且前端需配置 withCredentials: true。