在 nginx 中实现请求参数的重写与传递,核心在于利用 rewrite 指令修改 uri 路径,并通过 args 变量或 $query_string 控制查询字符串的保留、追加或覆盖。默认情况下,nginx 在处理重定向时会自动附加原始查询参数,若需完全自定义参数结构,必须显式使用 ? 截断符配合新的参数列表。

如何在不丢失原有参数的情况下追加新参数
当需要在保留客户端原始查询字符串的基础上增加特定参数时,应使用 rewrite 指令并省略末尾的 ? 符号。这种写法会触发 Nginx 的默认行为,即自动将当前请求的 $query_string 拼接到重写后的 URI 之后,从而实现参数的透明传递与合并。

server {
listen 80;
server_name example.com;
location /api/old {
# 匹配 /api/old?key=value
# 重写为 /api/new/path
# 最终请求变为: /api/new/path?key=value
rewrite ^/api/old(.*)$ /api/new/path break;
}
}
上述配置中,break 标志确保重写在当前 location 内完成,不继续向下匹配其他 location。客户端发起的请求如 /api/old?id=123,经过处理后内部转发至 /api/new/path?id=123,后端服务可同时获取到 id 参数。若希望同时添加固定参数,可结合 set 指令构造新字符串,但需注意手动拼接时的 URL 编码问题。
如何完全替换并重写查询参数
若业务逻辑要求忽略原始查询参数并强制使用一组全新的参数,必须在 rewrite 指令的目标 URI 后显式添加 ? 符号。该符号作为分隔符,告诉 Nginx 丢弃原有的 $query_string,仅保留其后跟随的新参数内容。这是实现参数清洗或标准化传递的关键步骤。

server {
listen 80;
server_name example.com;
location /legacy {
# 匹配 /legacy?any=thing
# 重写为 /modern?version=2&format=json
# 原始参数 any=thing 被丢弃
rewrite ^/legacy(.*)$ /modern?version=2&format=json last;
}
}
在此场景中,无论客户端传入何种参数,请求最终都会以 /modern?version=2&format=json 的形式进入后端。使用 last 标志表示重写完成后,Nginx 将重新进行 location 匹配,适用于需要跳转至不同处理逻辑的场景。注意参数间的连接符应为 &,且在 HTML 上下文中需转义为 &,但在 Nginx 配置文件中直接使用 & 即可。
基于 $args 变量的条件参数过滤
当需要根据现有参数的值动态决定是否重写请求时,可利用 $args 或 $query_string 变量进行条件判断。例如,仅当参数 debug 存在时才执行特殊路由,否则保持原样或返回错误。这种机制常用于灰度发布或调试接口的开关控制。
server {
listen 80;
server_name example.com;
location /service {
if ($args ~ "debug=true") {
rewrite ^/service(.*)$ /service/debug$1 last;
}
# 默认处理逻辑
proxy_pass http://backend;
}
}
该配置通过正则表达式匹配 $args,若发现 debug=true,则重写路径并追加 /debug 后缀,同时保留其余参数。由于 if 指令在 Nginx 中的特殊性,建议将其限制在 location 块内,并避免嵌套复杂逻辑。此方法确保了参数传递的可控性,使后端能根据请求来源区分处理流程。











