0

Nginx rewrite参数保留4种方法对比

2026.05.30 | youres | 3次围观

为什么rewrite会丢失参数?

配置Nginx rewrite时,很多人遇到一个奇怪问题:重定向后URL里的查询参数(比如 ?utm_source=xxx)不见了。这不是bug,而是Nginx的有意设计。

核心原因:rewrite的替换字符串中一旦出现问号 ?,原请求的查询参数就会被清空。这是最常见的踩坑点。

# 这个规则会把原参数清空!
rewrite ^/old/(.*)$ /new/= last;

明白了原理,下面看4种保留参数的方法。

方法1:用 $is_args 拼接参数

这是最常用的方法。$is_args 的值取决于是否有参数:有参数时是 ?,没有时为空字符串。$args 是完整的查询字符串(不含问号)。

rewrite ^/old/(.*)$ /new/$is_args` last;

效果:原请求 /old/page?utm_source=google/new/page?utm_source=google,无参数时不会多出多余的 ?

优点:简单直观,适合大多数场景。
缺点:追加新参数时要注意避免双重问号。

方法2:替换字符串不加问号(自动保留原参数)

Nginx有个隐藏特性:如果rewrite替换字符串中不含问号,原查询参数会被自动追加到新URL后面。

# 不含?,Nginx自动保留原参数
rewrite ^/old/(.*)$ /new/ last;

优点:写法最简洁,不需要手动拼接。
缺点:无法选择性保留或覆盖特定参数。

方法3:用 try_files 替代rewrite

如果需求只是"请求转发到某个文件",try_files 比rewrite更合适。它是内部重定向,不改地址栏,也不会丢失查询参数。

location / {
    try_files $uri $uri/ /index.html;
}

SPA应用常用这个配置,整个过程中 ?xxx=yyy 始终保留。

优点:不丢参数,性能比rewrite好(无需正则匹配)。
缺点:只能做文件存在性检查,不能做复杂URL重写。

方法4:用 map 指令精细控制参数

需要条件性地保留、删除或修改查询参数时,map 是最强大的工具。它在 http 块中定义映射规则,根据条件动态生成参数字符串。

http {
    map $args $filtered_args {
        ~^(.*)(utm_source=[^&]*)(.*)$ $2;
        default $args;
    }
}
server {
    rewrite ^/old/(.*)$ /new/$filtered_args last;
}

优点:最灵活,可实现复杂的参数过滤逻辑。
缺点:配置复杂,需放在 http 块,不适合快速修改。

4种方法对比

方法适用场景优点缺点
$is_args`精确控制参数拼接简单直观追加新参数需防双重问号
替换字符串不含?简单重定向,保留全部原参数写法最简洁无法覆盖或删除指定参数
try_filesSPA、静态文件转发不丢参数,性能好不能做复杂URL重写
map 指令条件过滤、精细控制参数最灵活强大配置复杂

相关文章

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论