Nginx 配置说明(含原请求与实际请求示例)

🧩 一、基础反向代理配置

location /api/ {
    proxy_pass http://127.0.0.1:8080/;
}

说明:

  • 当请求路径以 /api/ 开头时,转发到本地的 8080 端口。
  • 注意:proxy_pass 末尾的 / 会影响路径拼接方式。
原请求 实际请求
http://example.com/api/user http://127.0.0.1:8080/user

🧩 二、去掉末尾 / 的代理

location /api/ {
    proxy_pass http://127.0.0.1:8080;
}

说明:

  • 末尾不带 /,则原始请求路径会直接拼接在 proxy_pass 后面。
原请求 实际请求
http://example.com/api/user http://127.0.0.1:8080/api/user

🧩 三、前缀重写(rewrite)

location /napcat/ {
    rewrite ^/napcat/(.*)$ /$1 break;
    proxy_pass http://127.0.0.1:3000/;
}
原请求 实际请求
http://example.com/napcat/index.html http://127.0.0.1:3000/index.html

🧩 四、统一前缀代理(强制加上前缀)

location /napcat/ {
    proxy_pass http://127.0.0.1:3000/napcat/;
}
原请求 实际请求
http://example.com/napcat/index.html http://127.0.0.1:3000/napcat/index.html

🧩 五、子路径重定向(带正则)

location ~ ^/old/(.*)$ {
    rewrite ^/old/(.*)$ /new/$1 permanent;
}
原请求 实际请求
http://example.com/old/test 浏览器跳转到 http://example.com/new/test

🧩 六、子路径静态资源映射

location /static/ {
    alias /var/www/assets/;
}
原请求 实际访问文件
http://example.com/static/logo.png /var/www/assets/logo.png

🧩 七、反向代理 + WebSocket

location /ws/ {
    proxy_pass http://127.0.0.1:8081/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}
原请求 实际请求
ws://example.com/ws/chat ws://127.0.0.1:8081/chat

🧩 八、前端 Vue/React 路由转发

location / {
    try_files $uri $uri/ /index.html;
}
原请求 实际请求文件
http://example.com/dashboard /index.html

🧩 九、跨域配置 (CORS)

location /api/ {
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers '*';
    if ($request_method = OPTIONS) {
        return 204;
    }
    proxy_pass http://127.0.0.1:8080/;
}
原请求 实际请求
http://frontend.com/api/user http://127.0.0.1:8080/user

🧩 十、完整前后端分离项目示例

server {
    listen 80;
    server_name example.com;

    location / {
        root /var/www/frontend;
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass http://127.0.0.1:8080/;
    }
}
原请求 实际目标
http://example.com/ /var/www/frontend/index.html
http://example.com/api/user http://127.0.0.1:8080/user

Nginx 高阶用法

🧭应用场景

在实际项目中,可能存在 多个服务(如前端管理界面与主服务)共享同一域名 的需求。例如:

  • /webui/ 为前端控制台或管理界面(由 napcat_cluster 服务提供)
  • /api/ 为后端接口(通常由 komari_cluster 服务提供)

但当用户从 /webui/ 页面发起子请求时,仍希望其访问 napcat_cluster/api/ 接口。即:

根据 Referer 来源动态判断 /api/ 请求应被转发到哪个服务。

🧩upstream 定义

# WebUI 服务
upstream napcat_cluster {
    server 127.0.0.1:8081;
    keepalive 32;
}

# 主服务 API
upstream komari_cluster {
    server 127.0.0.1:8082;
    keepalive 32;
}

🧩 方案一:基于 if 判断的动态分发(传统实现)

📜 配置示例

server {
    listen 80;
    server_name example.com;
    # WebUI 主页面
	location /webui/ {
    	proxy_pass http://napcat_cluster;
	}

	# API 服务根据 Referer 分发
	location /api/ {
    	# 默认访问 komari_cluster
    	set $api_komaro "1";

    	# 若 Referer 来源于 /webui/ 页面,则改发往 napcat_cluster
    	if ($http_referer ~* "http(s)?://[^/]+/webui/?") {
        	proxy_pass http://napcat_cluster; # WebUI 服务的 API
        	set $api_komaro "";
    	}

    	# 否则访问默认的 komari_cluster
    	if ($api_komaro) {
        	proxy_pass http://komari_cluster;
    	}

    	proxy_http_version 1.1;
    	proxy_buffering off;
    	proxy_request_buffering off;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Connection "upgrade";
    	proxy_set_header Host $host;
    	proxy_set_header X-Forwarded-For $remote_addr;
	}
}

✅ 优点

  • 逻辑清晰直观,容易理解。
  • 可灵活添加复杂判断逻辑。

⚠️ 缺点

  • iflocation 中使用受限(某些位置不允许)。
  • 多次 proxy_pass 会有执行先后顺序问题,不易维护。

🚀 方案二:map 映射方式(推荐实现 ✅)

📜 配置示例

# 根据 Referer 映射目标 upstream
map $http_referer $komari_api_upstream {
    default                      http://komari_cluster;
    ~*https?://[^/]+/webui/?     http://napcat_cluster;
}
server {
    listen 80;
    server_name example.com;
	# WebUI 主页面
	location /webui/ {
    	proxy_pass http://napcat_cluster;
	}

	# API 请求根据 map 映射结果动态分发
	location /api/ {
    	proxy_pass $komari_api_upstream; # 动态转发到不同服务

    	proxy_http_version 1.1;
    	proxy_buffering off;
    	proxy_request_buffering off;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Connection "upgrade";
    	proxy_set_header Host $host;
    	proxy_set_header X-Forwarded-For $remote_addr;
	}
}

✅ 优势

  • 性能高(map 在 rewrite 阶段完成判断);
  • 语义清晰、安全;
  • 易维护;
  • 生产环境推荐使用。

📘 工作流程图

flowchart TD A[用户访问 /webui/] --> B[Nginx转发napcat_cluster] B --> C[页面内请求/api/getUser] C --> D[Nginx检查Referer] D -->|来自/webui/| E[napcat_cluster] D -->|否则|F[komari_cluster]

🧠 行为说明

场景 原请求 实际转发
用户直接访问 /api/xxx https://example.com/api/xxx komari_cluster
用户在 /webui/ 页面中发起的 /api/xxx 请求 Referer: https://example.com/webui/ napcat_cluster

🧮 对比总结

对比项 方案一(if 判断) 方案二(map 映射)
判断机制 请求阶段逐条执行 if 请求进入前通过 map 预映射
性能 中等 ✅ 高效
兼容性 较低(受限于 Nginx 语法) ✅ 高
安全性 ⚠️ 存在语法风险 ✅ 官方推荐
可维护性 一般 ✅ 简洁清晰
适用场景 临时验证、快速调试 ✅ 稳定生产环境
推荐级别 ⭐⭐ 🌟🌟🌟🌟🌟

结论
若需根据 Referer 智能路由 /api/ 请求到不同服务,
使用 map 映射方案 是最佳实践。