nginx实现多应用同域名下路径级动态302跳转,需用location前缀匹配+return 302,支持参数透传、灰度跳转及curl验证。

Nginx 在多应用共享同一域名(如 app.example.com)时,要实现路径级的动态临时跳转,关键不是“全局跳”,而是按请求路径精准识别、按需触发 302、保留参数、不干扰其他服务。核心思路是:用 location 做路径匹配 + return 302 做轻量跳转,避免 rewrite 循环或逻辑污染。
路径前缀匹配,只对特定模块临时切流
当多个应用共用 app.example.com,比如 /admin/ 给运维系统、/api/v1/ 给旧后端、/checkout/ 要临时切到新支付服务时:
- 用
location ^~ /checkout/这类前缀匹配,高效且不触发正则开销 -
return 302直接终止当前处理,不会误入后续proxy_pass或静态规则
server {
listen 80;
server_name app.example.com;
# 仅 /checkout/ 及其子路径临时跳转
location ^~ /checkout/ {
return 302 https://pay-new.example.com$uri?$args;
}
# 其他路径照常代理到对应应用(如旧 API)
location /api/v1/ {
proxy_pass http://legacy-api;
}
location /admin/ {
proxy_pass http://admin-backend;
}
# 默认走主应用
location / {
proxy_pass http://main-app;
}
}
动态路径拼接,支持参数透传与路径映射
有些场景需要把 /old-path?id=123 映射为 /new-path?from=old&id=123,这时不能只靠 $request_uri:
-
$request_uri包含原始完整串(含问号),适合原样透传 -
$uri?$args更可控,可手动拼接新查询参数,避免空?或重复参数
例如将 /promo/2024 跳到 /campaign/2024?source=promo:
location ^~ /promo/ {
# 提取路径尾部(如 2024),并拼新地址
rewrite ^/promo/(.*)$ /campaign/$1?source=promo&$args redirect;
}
⚠️ 注意:
rewrite ... redirect等效于 302,但必须加redirect;若用return,需写完整 URL:return 302 https://app.example.com/campaign/?source=promo&$args;
按条件做灰度式路径跳转(如 cookie 或 header)
想让带 X-Stage: beta 的请求,把 /user/profile 临时跳到新版本接口,其余不变:
- 优先用
map预定义变量,比if更安全、性能更好 -
map可基于$http_x_stage、$cookie_user_type等生成跳转开关
map $http_x_stage $should_beta_redirect {
default "";
"beta" 1;
}
server {
listen 80;
server_name app.example.com;
location = /user/profile {
if ($should_beta_redirect) {
return 302 https://api-beta.example.com/v2/profile$uri?$args;
}
proxy_pass http://legacy-api;
}
}
✅
map+if组合在简单判断下是可接受的;避免在if中嵌套proxy_pass或复杂正则
验证是否真跳、跳得对
配置 reload 后,别只刷浏览器:
- 用
curl -I http://app.example.com/checkout/submit看响应头是否含HTTP/1.1 302 Found和正确Location - 测试带参数的 URL,确认
?ref=abc&utm_medium=email没丢 - 用无痕窗口多次访问,排除浏览器缓存干扰(302 默认不缓存,但反复测试可能残留)
基本上就这些。











