Nginx接口聚合与跨域处理
🎯 引言
🚀 1. 什么是接口聚合?
在现代前端开发中,proxy_pass 就像一个"万能适配器",它能帮我们将多个后端API整合成一个统一的入口。想象一下,你作为前端开发,面对着多个不同域名、不同端口的后端服务,而proxy_pass就是那个帮你把这些服务统一起来的"翻译官"。
🎪 2. 为什么需要跨域处理?
老曹我干了这么多年前端,深知跨域问题是每个前端工程师的"噩梦"!无论是开发环境还是生产环境,跨域问题总是让人头疼。没有合理的处理方案?那你就等着被OPTIONS请求刷屏吧,那种挫败感比联调时遇到后端改了接口文档却不通知你的感觉还要糟。
💡 3. 本章核心价值
接口聚合和跨域处理不只是技术活儿,更是协作的艺术!掌握好了,你就是团队里的"跨域大脑 “,能让前后端协作顺畅无比;掌握不好,你就是项目的"绊脚石”,只会制造各种奇怪的问题。
🎯 学习目标
📋 1. 核心技能要求
- 熟练掌握 proxy_pass 代理转发配置
- 深入理解 CORS跨域资源共享机制
- 灵活运用 预检请求OPTIONS的处理
- 解决实际 微服务架构下的接口聚合问题
🎯 2. 实践能力培养
- 独立设计 多后端统一入口方案
- 高效处理 复杂的跨域场景
- 优化性能 提升接口聚合效率
🧠 原理解析
🔄 3. 代理工作流程
#mermaid-svg-TSxDplZan4220Apy{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TSxDplZan4220Apy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TSxDplZan4220Apy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TSxDplZan4220Apy .error-icon{fill:#552222;}#mermaid-svg-TSxDplZan4220Apy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TSxDplZan4220Apy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TSxDplZan4220Apy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TSxDplZan4220Apy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TSxDplZan4220Apy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TSxDplZan4220Apy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TSxDplZan4220Apy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TSxDplZan4220Apy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TSxDplZan4220Apy .marker.cross{stroke:#333333;}#mermaid-svg-TSxDplZan4220Apy svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TSxDplZan4220Apy p{margin:0;}#mermaid-svg-TSxDplZan4220Apy .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-TSxDplZan4220Apy .cluster-label text{fill:#333;}#mermaid-svg-TSxDplZan4220Apy .cluster-label span{color:#333;}#mermaid-svg-TSxDplZan4220Apy .cluster-label span p{background-color:transparent;}#mermaid-svg-TSxDplZan4220Apy .label text,#mermaid-svg-TSxDplZan4220Apy span{fill:#333;color:#333;}#mermaid-svg-TSxDplZan4220Apy .node rect,#mermaid-svg-TSxDplZan4220Apy .node circle,#mermaid-svg-TSxDplZan4220Apy .node ellipse,#mermaid-svg-TSxDplZan4220Apy .node polygon,#mermaid-svg-TSxDplZan4220Apy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TSxDplZan4220Apy .rough-node .label text,#mermaid-svg-TSxDplZan4220Apy .node .label text,#mermaid-svg-TSxDplZan4220Apy .image-shape .label,#mermaid-svg-TSxDplZan4220Apy .icon-shape .label{text-anchor:middle;}#mermaid-svg-TSxDplZan4220Apy .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-TSxDplZan4220Apy .rough-node .label,#mermaid-svg-TSxDplZan4220Apy .node .label,#mermaid-svg-TSxDplZan4220Apy .image-shape .label,#mermaid-svg-TSxDplZan4220Apy .icon-shape .label{text-align:center;}#mermaid-svg-TSxDplZan4220Apy .node.clickable{cursor:pointer;}#mermaid-svg-TSxDplZan4220Apy .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-TSxDplZan4220Apy .arrowheadPath{fill:#333333;}#mermaid-svg-TSxDplZan4220Apy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TSxDplZan4220Apy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TSxDplZan4220Apy .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TSxDplZan4220Apy .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TSxDplZan4220Apy .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TSxDplZan4220Apy .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-TSxDplZan4220Apy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TSxDplZan4220Apy .cluster text{fill:#333;}#mermaid-svg-TSxDplZan4220Apy .cluster span{color:#333;}#mermaid-svg-TSxDplZan4220Apy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-TSxDplZan4220Apy .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TSxDplZan4220Apy rect.text{fill:none;stroke-width:0;}#mermaid-svg-TSxDplZan4220Apy .icon-shape,#mermaid-svg-TSxDplZan4220Apy .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TSxDplZan4220Apy .icon-shape p,#mermaid-svg-TSxDplZan4220Apy .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-TSxDplZan4220Apy .icon-shape rect,#mermaid-svg-TSxDplZan4220Apy .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TSxDplZan4220Apy .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-TSxDplZan4220Apy .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-TSxDplZan4220Apy :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
前端发起请求
Nginx接收请求
匹配location规则
转发到后端服务
修改请求头
后端处理请求
返回响应
处理响应头
添加CORS头
返回给前端
🔍 4. 详细流程说明
📌 4.1 请求拦截
当请求进入Nginx时,首先会按照location 规则进行匹配。这个过程就像找钥匙开锁一样,只有找到对应的钥匙(规则)才能打开门(执行代理转发)。
📌 4.2 代理转发
在匹配到的location 块内,Nginx会使用proxy_pass 指令将请求转发到指定的后端服务。同时会处理各种请求头,确保后端服务能正确识别原始请求信息。
📌 4.3 响应处理
后端服务返回响应后,Nginx会对响应头进行处理,特别是添加CORS相关头部,确保前端能正常接收响应数据。
🛠️ 语法详解
📖 5. proxy_pass基本语法
proxy_pass URL;
常见的配置选项:
- proxy_set_header: 设置转发时的请求头
- proxy_redirect: 修改响应中的重定向地址
- proxy_connect_timeout: 连接超时时间
- proxy_send_timeout: 发送超时时间
- proxy_read_timeout: 读取超时时间
📊 6. 常用代理配置对照表
| proxy_pass | 代理目标地址 | proxy_pass http://backend; |
| proxy_set_header | 设置请求头 | proxy_set_header Host $host; |
| proxy_redirect | 重写重定向 | proxy_redirect off; |
| proxy_buffering | 是否启用缓冲 | proxy_buffering on; |
📝 实战配置
🎯 7. 基础代理配置
# 简单的代理配置
upstream api_backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 32;
}
server {
listen 80;
server_name api.example.com;
# API接口代理
location /api/ {
proxy_pass http://api_backend/;
# 传递原始请求头
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;
# 设置超时时间
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
🎯 8. 多服务聚合配置
# 用户服务
upstream user_service {
server user-api.example.com:8080;
}
# 订单服务
upstream order_service {
server order-api.example.com:8081;
}
# 商品服务
upstream product_service {
server product-api.example.com:8082;
}
server {
listen 80;
server_name gateway.example.com;
# 用户相关接口
location /api/user/ {
proxy_pass http://user_service/;
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;
# 添加CORS头部
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
# 处理预检请求
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
add_header Access-Control-Max-Age 1728000;
add_header Content-Type text/plain charset=utf-8;
add_header Content-Length 0;
return 204;
}
}
# 订单相关接口
location /api/order/ {
proxy_pass http://order_service/;
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;
# CORS配置
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
}
# 商品相关接口
location /api/product/ {
proxy_pass http://product_service/;
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;
# CORS配置
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
}
}
🎯 9. 静态资源与API混合配置
# 前端应用配置
upstream frontend_app {
server 127.0.0.1:3000;
}
# 后端API配置
upstream backend_api {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name app.example.com;
root /var/www/app;
# API接口代理
location /api/ {
proxy_pass http://backend_api/;
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;
# 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' always;
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With' always;
# 处理预检请求
if ($request_method = 'OPTIONS') {
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';
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With';
add_header Access-Control-Max-Age 86400;
return 204;
}
}
# 静态资源处理
location ~* \\.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# SPA应用路由处理
location / {
try_files $uri $uri/ @frontend;
}
location @frontend {
proxy_pass http://frontend_app;
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;
}
}
🛡️ 高级技巧
🎯 10. 动态CORS配置
# 根据请求来源动态设置CORS
map $http_origin $cors_origin {
default "*";
"~^https?://localhost:[0-9]+" "$http_origin";
"~^https?://app\\.example\\.com" "$http_origin";
"~^https?://dev\\.example\\.com" "$http_origin";
}
server {
listen 80;
server_name api.example.com;
location /api/ {
proxy_pass http://backend_api/;
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;
# 动态CORS配置
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Credentials true always;
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, PATCH, OPTIONS' always;
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header Access-Control-Expose-Headers 'Content-Length,Content-Range' always;
# 预检请求处理
if ($request_method = 'OPTIONS') {
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, PATCH, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header Access-Control-Max-Age 86400;
return 204;
}
}
}
🎯 11. 负载均衡与健康检查
# 配置后端服务集群
upstream user_api_cluster {
server user-api-1.example.com:8080 weight=3 max_fails=2 fail_timeout=30s;
server user-api-2.example.com:8080 weight=2 max_fails=2 fail_timeout=30s;
server user-api-3.example.com:8080 backup;
# 保持连接
keepalive 32;
}
server {
listen 80;
server_name api.example.com;
location /api/users/ {
# 启用连接池
proxy_pass http://user_api_cluster;
# 保持长连接
proxy_http_version 1.1;
proxy_set_header Connection "";
# 设置请求头
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;
# 超时配置
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 30s;
# CORS配置
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
# 预检请求处理
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
add_header Access-Control-Max-Age 1728000;
return 204;
}
}
}
📋 面试题解析
❓ 12. 十大经典面试题
✅ 1. proxy_pass 中的斜杠有什么作用?
答:
- proxy_pass http://backend/; – 会将location匹配的部分替换为/
- proxy_pass http://backend; – 会保留原始URI路径
✅ 2. CORS预检请求什么时候触发?
答:
- 请求方法不是GET、POST、HEAD之一
- 请求头包含自定义头部
- Content-Type为application/json、multipart/form-data等
✅ 3. 如何处理带credentials的跨域请求?
答:
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
注意不能使用通配符"*"。
✅ 4. proxy_set_header 的常见用途?
答:
- 传递原始客户端IP
- 保持Host头一致
- 传递协议信息
✅ 5. 如何防止代理循环?
答:
- 检查proxy_pass目标是否指向自身
- 使用X-Forwarded-For避免重复添加
- 设置适当的超时时间
✅ 6. proxy_buffering 的作用是什么?
答:
- on: 启用缓冲,先接收完整响应再发送给客户端
- off: 关闭缓冲,边接收边发送
✅ 7. 如何处理WebSocket连接?
答:
location /ws/ {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
✅ 8. try_files 和 proxy_pass 可以配合使用吗?
答:
可以,常用于SPA应用,先尝试静态文件,不存在则代理到前端服务。
✅ 9. 如何限制请求体大小?
答:
client_max_body_size 10M;
✅ 10. 如何添加自定义响应头?
答:
add_header X-Response-Time $request_time;
add_header X-Powered-By "Nginx";
📊 配置对比表
🎯 13. 代理策略对比
| 简单代理 | proxy_pass | 配置简单 | 功能单一 | ★★★★★ |
| 负载均衡 | upstream + proxy_pass | 高可用 | 配置复杂 | ★★★★☆ |
| CORS处理 | add_header | 灵活控制 | 安全风险 | ★★★★☆ |
| 动态路由 | map + proxy_pass | 智能路由 | 性能开销 | ★★★☆☆ |
| 缓存代理 | proxy_cache | 性能提升 | 内存占用 | ★★★★☆ |
🎯 14. CORS头部配置指南
| Access-Control-Allow-Origin | 允许的源 | 避免使用* |
| Access-Control-Allow-Methods | 允许的方法 | 限制必要方法 |
| Access-Control-Allow-Headers | 允许的头部 | 限制敏感头部 |
| Access-Control-Allow-Credentials | 允许凭据 | 配合特定源使用 |
🛠️ 实践案例
🎯 15. 微服务网关配置
# 微服务网关完整配置示例
upstream auth_service {
server auth-service:8080;
}
upstream user_service {
server user-service:8080;
}
upstream order_service {
server order-service:8080;
}
upstream payment_service {
server payment-service:8080;
}
upstream notification_service {
server notification-service:8080;
}
server {
listen 80;
server_name gateway.example.com;
# 认证服务
location /auth/ {
proxy_pass http://auth_service/;
include proxy_params;
# 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' always;
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With' always;
# 预检请求处理
if ($request_method = 'OPTIONS') {
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';
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With';
add_header Access-Control-Max-Age 86400;
return 204;
}
}
# 用户服务
location /users/ {
proxy_pass http://user_service/;
include proxy_params;
# 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' always;
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With' always;
# 预检请求处理
if ($request_method = 'OPTIONS') {
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';
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With';
add_header Access-Control-Max-Age 86400;
return 204;
}
}
# 订单服务
location /orders/ {
proxy_pass http://order_service/;
include proxy_params;
# 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' always;
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With' always;
# 预检请求处理
if ($request_method = 'OPTIONS') {
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';
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With';
add_header Access-Control-Max-Age 86400;
return 204;
}
}
# 支付服务
location /payments/ {
proxy_pass http://payment_service/;
include proxy_params;
# 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' always;
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With' always;
# 预检请求处理
if ($request_method = 'OPTIONS') {
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';
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With';
add_header Access-Control-Max-Age 86400;
return 204;
}
}
# 通知服务
location /notifications/ {
proxy_pass http://notification_service/;
include proxy_params;
# 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' always;
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With' always;
# 预检请求处理
if ($request_method = 'OPTIONS') {
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';
add_header Access-Control-Allow-Headers 'Accept, Authorization, Cache-Control, Content-Type, DNT, If-Modified-Since, Keep-Alive, Origin, User-Agent, X-Requested-With';
add_header Access-Control-Max-Age 86400;
return 204;
}
}
}
# 通用代理参数
upstream backend {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://backend;
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;
proxy_redirect off;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
🔍 调试技巧
🎯 16. 代理调试方法
🐛 16.1 开启代理日志
# 在nginx.conf中添加
error_log /var/log/nginx/proxy_error.log debug;
access_log /var/log/nginx/proxy_access.log;
# 查看代理日志
tail -f /var/log/nginx/proxy_error.log
🔍 16.2 测试代理连通性
# 测试代理是否生效
curl -v http://your-domain.com/api/test
# 检查CORS头部
curl -I -H "Origin: http://localhost:3000" \\
-H "Access-Control-Request-Method: POST" \\
-H "Access-Control-Request-Headers: X-Requested-With" \\
-X OPTIONS http://your-domain.com/api/test
📈 性能监控
🎯 17. 代理性能指标
- 连接数: 并发连接数量
- 响应时间: 代理转发延迟
- 吞吐量: 每秒处理请求数
- 错误率: 代理失败比例
🎯 18. 优化建议
🎯 总结
📋 19. 核心要点回顾
✅ 19.1 必掌握技能
- proxy_pass 代理转发配置
- CORS跨域资源共享机制
- 预检请求OPTIONS的处理
⚠️ 19.2 注意事项
- 避免代理循环
- 注意安全性配置
- 合理设置超时时间
🚀 20. 进阶方向
掌握了基础的接口聚合和跨域处理后,你可以进一步学习:
- gRPC代理配置
- TLS终止和SSL卸载
- 高级负载均衡策略
📝 21. 前端实践心得
作为前端开发,我们经常需要在开发环境中配置代理来解决跨域问题。使用Nginx的proxy_pass功能,我们可以轻松地将前端开发服务器的API请求代理到后端服务:
# 开发环境代理配置
server {
listen 80;
server_name dev.example.com;
# 将API请求代理到后端
location /api/ {
proxy_pass http://localhost: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;
# 开发环境允许所有源
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
}
# 静态文件服务
location / {
root /path/to/your/frontend/build;
try_files $uri $uri/ /index.html;
}
}
老曹我常说,接口聚合就像团队协作,需要各方配合才能达到最佳效果。记住这些配置技巧,让前后端协作更加顺畅!
🎪 老曹金句: “好的代理配置应该像优秀的团队协调员,总能在合适的时候把任务分配给合适的队友!”


