Nginx rewrite指令本身不支持直接提取动态路由参数,但可通过正则捕获组(如(\d+))在location ~中匹配路径,并用$1、$2等变量在rewrite中引用拼接新路径,实现等效效果。

Nginx 的 rewrite 指令本身不支持直接提取并重用动态路由参数(如 /user/123 中的 123)来构造新路径,但它可以通过正则捕获 + $1、$2 等引用实现等效效果。关键在于:用 location 匹配路径,配合 rewrite 中的捕获组,把动态段“抽出来”再拼进目标 URL。
用正则捕获动态段并重写
这是最常用的方式。Nginx 在 rewrite 中使用 PCRE 正则,括号 () 表示捕获,匹配后的值通过 $1、$2 引用。
例如,把 /api/user/123/profile 重写为 /v2/users?id=123&tab=profile:
location ~ ^/api/user/(\d+)/(.+)$ {
rewrite ^/api/user/(\d+)/(.+)$ /v2/users?id=$1&tab=$2? last;
}
说明:
-
location ~ ^/api/user/(\d+)/(.+)$:启用正则匹配,并捕获数字 ID 和后续路径段 -
rewrite ... $1和$2:分别对应第一个和第二个括号里的内容 -
?结尾:阻止 Nginx 自动追加原始 query string(避免重复参数) -
last:终止当前 cycle,用新 URI 重新匹配 location
保留原始查询参数并追加动态值
如果原请求带查询参数(如 /post/42?from=feed),又想保留它们并补充动态 ID,可利用 $args 变量:
location ~ ^/post/(\d+)$ {
rewrite ^/post/(\d+)$ /article.php?id=$1&$args? last;
}
这样访问 /post/42?from=feed&ref=share 就会变成:/article.php?id=42&from=feed&ref=share
注意:$args 是原始 query string 的完整字符串(不含 ?),所以后面要加 & 连接。
配合 proxy_pass 实现后端路由透传
很多场景下不是重写到本地文件,而是转发给上游服务(如 Node.js 或 Go API)。此时建议用 proxy_pass + 路径重写,更清晰可靠:
location ~ ^/app/(\w+)/(\d+)$ {
proxy_set_header X-Original-URI $request_uri;
proxy_pass http://backend/$1?id=$2;
}
说明:
-
proxy_pass后带路径(如/user)时,Nginx 会自动替换匹配的前缀 - 但这里用了变量
$1,属于“带变量的 proxy_pass”,Nginx 不会自动剪裁路径,需确保 URI 构造准确 -
X-Original-URI可供后端记录原始请求路径
避免常见陷阱
动态 rewrite 容易出错,注意以下几点:
- 正则开头加
^、结尾加$,防止误匹配(比如/user/1234被/user/123规则提前截断) - 多个
rewrite规则按顺序执行,last会重启匹配,break则停止 rewrite 但继续执行后续配置 - 捕获组数量必须与
$1、$2使用一致,否则为空字符串 - 中文或特殊字符路径需确认 Nginx 编译时启用了
--with-pcre-jit并正确处理 UTF-8











