$request_uri是首选,因它原样保留客户端发送的完整URI(含路径及所有查询参数),无需拼接$args,配置简洁、语义明确、兼容性强;而$uri不含参数,易导致丢参。

直接用 $request_uri 就能完整保留路径和所有查询参数,这是最稳妥、最推荐的做法。
为什么 $request_uri 是首选
它原样捕获客户端发来的完整 URI,包括斜杠后的路径和问号后的全部参数(如 /product?id=123&utmsource=wechat)。不像 $uri 只含路径部分,也不需要额外拼接 $args,避免遗漏或重复。
- 配置简洁:一行
return 301 https://$host$request_uri;即可 - 语义明确:不依赖正则匹配,无隐式截断风险
- 兼容性强:对含特殊字符、中文、多重编码的参数也稳定生效
常见错误写法及后果
很多配置看似正常,实则悄悄丢参:
-
return 301 https://$host$uri;→ 丢失所有?key=value参数 -
rewrite ^(.*)$ https://$host$1 permanent;→ 若未显式加$args,参数同样清空 -
rewrite ^/old /new permanent;→ 路径替换后,原始参数彻底消失
需要过滤或定制参数时怎么办
当只保留特定参数(比如仅透传 bayy 或 utm_*),可用 if + set 提前提取:
- 匹配并保存:
if ($args ~* "(^|&)bayy=([^&]*)&?") { set $saved_bayy $2; } - 构造跳转:
return 301 https://$host/new-path?bayy=$saved_bayy; - 多个参数可叠加判断,或用 map 指令做更清晰的映射
反向代理场景下的参数延续
如果重定向实际是通过 proxy_pass 实现(比如前端统一入口),注意末尾斜杠:
-
proxy_pass https://backend;→ 不带斜杠,会丢参 -
proxy_pass https://backend/;→ 带斜杠,自动透传完整请求路径与参数 - 配合
proxy_set_header X-Forwarded-For $remote_addr;等头信息,便于后端识别原始请求


















