nginx中代理与重定向机制不同:proxy_pass转发请求且地址栏不变,return/rewrite触发跳转且地址栏改变;实际常组合使用,如条件跳转、路径重写后代理、基于请求头动态路由,并需规避if直接proxy_pass、rewrite循环等陷阱。

Nginx 中 HTTP 代理本身不直接“设置重定向策略”,因为代理(proxy_pass)和重定向(return/rewrite)是两类不同机制:
代理是把请求悄悄转发给后端,用户地址栏不变;重定向是告诉浏览器跳去另一个 URL,地址栏会变。
但实际中常需组合使用——比如先根据条件判断是否该跳转,再决定是否代理;或重写路径后再代理。下面分场景讲清楚怎么配。
域名或路径级强制跳转(纯重定向)
适合旧站迁移、HTTP→HTTPS、多域名归一等场景,不涉及后端代理。
- 用 return 301 最简洁高效,避免正则开销和循环风险:
server {
listen 80;
server_name old.com;
return 301 https://new.com$request_uri;
} - 跳转到 HTTPS(含域名):
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
} - 只改路径不改域名:
location /old-path {
return 301 /new-path$request_uri;
}
路径重写 + 反向代理(常用组合)
前端统一入口、API 路径标准化时典型用法:先改路径,再发给后端。
-
rewrite + proxy_pass 配合 break(推荐):
location /api/v2/ {
rewrite ^/api/v2/(.*)$ /v2/$1 break;
proxy_pass http://backend:8000;
proxy_set_header Host $host;
}
→ 请求/api/v2/user被内部改写为/v2/user,再发给后端。 - 注意 proxy_pass 结尾斜杠:
proxy_pass http://backend/;→ 剥掉匹配前缀;proxy_pass http://backend;→ 完整路径透传(通常不想要)。
按请求头动态路由(带条件的代理或跳转)
灰度发布、环境隔离、A/B 测试等场景,靠 Header 决定走向。
- 用 $http_x_env 等变量读取 Header(自动转小写+下划线):
X-Env: staging→ 变量为$http_x_env - Header 匹配后跳转:
if ($http_x_env = "staging") {
rewrite ^(.*)$ https://staging.example.com$1 redirect;
} - 更健壮的做法:用 set 定义后端变量,再 proxy_pass 引用:
set $backend "http://default:8000";
if ($http_x_env = "prod") { set $backend "http://prod:9000"; }
if ($http_x_env = "dev") { set $backend "http://dev:9001"; }
proxy_pass $backend;
常见陷阱与验证要点
配置生效前务必确认这些细节,否则容易 500、404 或无限跳转。
- if 块不能直接放 proxy_pass:Nginx 不允许,必须用变量中转。
-
rewrite 的 last vs break:
last会重新匹配 location,可能触发循环(尤其在location /下);break终止当前块 rewrite,继续执行后续 proxy_pass,更安全。 - 调试时加
rewrite_log on;和error_log /path/log notice;查重写过程。 - 测试用 curl -I 看响应头 Location 和状态码,确认是 301/302 还是 200。











