全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 8 分钟 ✍️ juanwangdev

Nginx反向代理解决跨域

Nginx反向代理是生产环境解决跨域问题的常用方案,无需修改后端代码。

原理分析

nginx
浏览器  -->  Nginx(同源)  -->  后端服务
      同源请求        跨域转发

浏览器只与Nginx交互,通过同源策略检查,跨域问题由Nginx内部解决。

基础配置

统一入口代理

JavaScript
server {
    listen 80;
    server_name example.com;

    # 前端静态资源
    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    # API代理到后端
    location /api/ {
        proxy_pass http://backend-server:8080/;
        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 X-Forwarded-Proto $scheme;
    }
}

前端请求示例:

nginx
// 浏览器访问 http://example.com
// API请求直接发往同源地址
fetch('/api/users')  // 实际请求 http://backend-server:8080/users

响应头配置方案

添加CORS响应头

nginx
server {
    listen 80;
    server_name api.example.com;

    location / {
        # 后端服务地址
        proxy_pass http://localhost:8080;

        # CORS配置
        add_header Access-Control-Allow-Origin $http_origin always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
        add_header Access-Control-Allow-Credentials true always;
        add_header Access-Control-Max-Age 3600 always;

        # 处理预检请求
        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 "Content-Type, Authorization";
            add_header Access-Control-Allow-Credentials true;
            add_header Access-Control-Max-Age 3600;
            add_header Content-Length 0;
            return 204;
        }
    }
}

动态Origin白名单

使用map指令

nginx
# 定义允许的源映射
map $http_origin $cors_origin {
    default "";
    "http://localhost:3000" "http://localhost:3000";
    "http://localhost:4000" "http://localhost:4000";
    "http://example.com"    "http://example.com";
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://localhost:8080;

        # 使用映射变量
        add_header Access-Control-Allow-Origin $cors_origin always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, 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 Access-Control-Allow-Origin $cors_origin;
            add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
            add_header Access-Control-Allow-Headers "Content-Type, Authorization";
            add_header Access-Control-Allow-Credentials true;
            add_header Content-Length 0;
            return 204;
        }
    }
}

多服务代理配置

nginx
server {
    listen 80;
    server_name example.com;

    # 前端应用
    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }

    # 用户服务
    location /api/user/ {
        proxy_pass http://user-service:8081/;
    }

    # 订单服务
    location /api/order/ {
        proxy_pass http://order-service:8082/;
    }

    # 商品服务
    location /api/product/ {
        proxy_pass http://product-service:8083/;
    }
}

WebSocket支持

text
location /ws/ {
    proxy_pass http://backend:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 86400;
}

方案对比

方案优点缺点适用场景
反向代理无需修改代码,统一入口增加Nginx层生产环境
响应头配置灵活控制需处理预检前后端分离
动态白名单安全可控配置复杂多前端源

要点总结

  • 反向代理通过统一入口解决跨域,浏览器无需关心后端地址
  • 使用map指令可实现动态Origin白名单
  • 预检请求需要单独处理返回204
  • 生产环境推荐使用反向代理方案
  • 配置WebSocket时需要添加升级头

📝 发现内容有误?点击此处直接编辑

← 上一篇 CORS协议详解
下一篇 → SpringMVC CORS配置
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库