Nginx中proxy_pass默认保留查询字符串,无需额外配置;但proxy_pass后带URI路径(尤其以/结尾)或手动拼接URL时会丢失,需显式使用$args或$is_args$args补全。

在 Nginx 中使用 proxy_pass 时,默认就会保留原始请求的查询字符串(query string),**无需额外配置**。只要写法正确,问号后面的所有参数会自动透传到上游服务。
确保 query string 被保留的关键点
以下情况会导致查询字符串丢失,需避免:
-
proxy_pass 后面带了 URI 路径(尤其是以
/结尾)且重写了 location 路径:Nginx 会丢弃原始 query string,除非显式用$args或$is_args$args补上。 -
在 proxy_pass 指令中手动拼接 URL 并遗漏
$args:例如写成proxy_pass http://backend/foo?bar=1;,这样原始参数就完全被覆盖了。 - 用了 rewrite + break/redirect,但没传递 $args:rewrite 本身不自动携带参数,需显式追加。
推荐写法:直接代理,不改路径
这是最安全、最常用的方式,query string 自动保留:
location /api/ {
proxy_pass http://127.0.0.1:8000/;
}说明:
- 请求 /api/users?id=123&name=test
- 会转发给上游 http://127.0.0.1:8000/users?id=123&name=test
- 注意末尾的 /:它表示“替换掉匹配的 /api/”,同时保留剩余路径和 query string。
需要改写路径时,显式携带 $args
如果用 rewrite 修改了 URI,或 proxy_pass 不带尾部斜杠,需手动补上参数:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
location /old/ {
rewrite ^/old/(.*)$ /new/$1 break;
proxy_pass http://backend;
proxy_set_header X-Original-Args $args;
}或者更稳妥地拼接完整 URL:
location /v1/ {
proxy_pass http://backend/v2/?$args;
}⚠️ 注意:$args 是已编码的原始参数;$is_args$args 更严谨(当无参数时自动补 ?,有参数时补 &),但多数场景用 $args 就够了。
验证是否生效的小技巧
可以在 upstream 服务里打印原始 request URI 或 query 字符串,或临时用 echo 服务测试:
location /test/ {
proxy_pass http://httpbin.org/get;
}访问 /test/?a=1&b=2,查看响应中的 args 字段,就能确认是否透传成功。

















