Nginx 的 proxy_pass 会把 query string 参数转发给后端吗?

默认会。proxy_pass 自动携带原始查询串;重写 URL(rewrite)或 proxy_pass 带 URI 部分时需注意 $args 与 is_args 的保留。自定义参数用 $args、$arg_ 变量操作。

最佳实践
Nginx 的 proxy_pass 会把 query string 参数转发给后端吗?封面

答案:默认会自动转发——proxy_pass http://backend; 时,客户端的查询串(?a=1&b=2)原样带给后端。需要自己操心的是两种"例外":proxy_pass 后面带了 URI 部分(如 proxy_pass http://backend/api;)的重写行为,以及 rewrite 指令默认会丢弃/重建参数。

默认行为:透传

location / {
    proxy_pass http://127.0.0.1:8080;
}

请求 /search?q=nginx&page=2 → 后端收到 /search?q=nginx&page=2。无需任何配置。

注意点一:proxy_pass 带 URI 部分

location /api/ {
    proxy_pass http://127.0.0.1:8080/;    # 注意结尾的 /
}
  • 带 URI(哪怕是 /):匹配前缀被替换——/api/users?x=1/users?x=1,参数仍保留
  • 不带 URI:/api/users?x=1/api/users?x=1 原样转发

两种写法参数都不会丢,丢的是路径前缀,别搞错。

注意点二:rewrite 的参数处理

rewrite ^/old/(.*)$ /new/$1;              # 默认保留原参数
rewrite ^/old/(.*)$ /new/$1?;             # 结尾 ? 表示丢弃原参数
rewrite ^/old/(.*)$ /new/$1?type=fixed;   # 自己的参数会替换掉原参数!

第三条里原 query string 被替换——想合并要显式带上 $args

rewrite ^/old/(.*)$ /new/$1?type=fixed&$args?;   # 不推荐这么绕

更干净的做法是用变量操作(见下)。

自定义/修改参数

location / {
    set $args $args&source=proxy;         # 追加参数
    # 或读取单个参数
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header X-User-Id $arg_uid;  # 取 ?uid= 的值放进 header
}
  • $args:完整查询串
  • $arg_名字:单个参数值
  • set $args ... 可整体改写

观测云对照

参数正确性从链路验证。 反代后参数丢失导致的后端 400,在观测云 APM 调用链里能看到后端实际收到的完整 URL,与前端请求比对即刻定界是代理层还是应用层问题。

常见问题(FAQ)

Q:参数被编码/解码了吗?
A:proxy_pass 透传时是规范化后的 URI;带 URI 部分替换时会做 URL 解码再编码,特殊字符场景注意测试。

Q:后端说参数乱码?
A:确认客户端→Nginx→后端的编码一致(UTF-8),Nginx 默认不改编码,乱码多在应用解码环节。

Q:怎么按参数值分流到不同后端?
A:if ($arg_env = test) { proxy_pass http://test-backend; },或更规整地用 map 指令映射 upstream。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台