在 nginx 中,`rewrite` 指令本身无法直接修改后端请求的查询参数(query string),因为 `proxy_pass` 会自动附加原始 uri 的参数。要实现将 http 协议参数传递给后端,必须使用 `set` 指令提取参数,并通过 `?` 符号显式拼接至 `proxy_pass` 的目标地址,从而覆盖默认行为。

如何从 URL 路径中提取参数并传给后端
通过正则表达式捕获路径中的特定片段,并使用 `set` 指令将其存入变量,最后在 `proxy_pass` 中引用该变量即可。

server {
listen 80;
server_name example.com;
location /api/ {
# 匹配 /api/12345 并捕获 12345
rewrite ^/api/(\d+)$ /backend?id=$1 break;
# 显式传递 id 参数
proxy_pass http://backend_server/?id=$1;
}
}
当访问 /api/12345 时,Nginx 会将请求转发给后端,URL 变为 /backend?id=12345。后端接收到的参数即为 id=12345。
如何处理多个参数或复杂映射
对于包含多个参数的场景,可以在正则中捕获多个组,并在 proxy_pass 中按顺序拼接。

server {
listen 80;
server_name example.com;
location /v2/ {
# 匹配 /v2/user/123/action/456
rewrite ^/v2/user/(\w+)/action/(\d+)$ /process?user=$1&action_id=$2 break;
# 传递 user 和 action_id
proxy_pass http://backend_server/?user=$1&action_id=$2;
}
}
此配置将 /v2/user/admin/action/999 转换为 /process?user=admin&action_id=999。注意 break 标志确保重写后不再继续匹配其他规则,且 proxy_pass 后的问号是强制传递参数的关键。
基于 proxy_pass 中问号缺失导致的参数丢失问题
如果 proxy_pass 地址后未加 ?,Nginx 会保留原始请求的查询字符串,导致自定义参数被忽略或冲突。
location /test/ {
set $my_param "value";
# 错误写法:缺少问号,原始参数会被追加
proxy_pass http://backend_server/test;
# 正确写法:添加问号,仅传递 my_param
proxy_pass http://backend_server/test?my_param=$my_param;
}
测试表明,不加 ? 时,请求 /test?a=1 会转发为 /test?a=1&my_param=value;而加上 ? 后,仅转发为 /test?my_param=value。因此,显式控制参数传递必须依赖 ? 符号。











