URL参数过滤非重写,而是处理查询字符串;Nginx rewrite默认只匹配路径不包含参数,需用$args配合if或map实现带参重写、参数清理或保留等操作。
URL 参数过滤本身不是重写,而是对查询字符串(即 ? 后面的部分)的处理。Nginx 的 rewrite 指令默认不碰参数——它只匹配路径($uri),不包含问号及之后内容。所以“带参重写”实际是:先判断参数,再改路径或调整参数本身。
这是最直接的方式,适合简单规则。注意 if 在 location 中慎用,但针对参数判断仍较常见。
utm_source=ad 的请求统一跳到首页且不带参数
if ($args ~ utm_source=ad) {rewrite ^/.*$ /? permanent;
}
id 和 lang,其他全去掉
if ($args ~* "id=([^&]+)&.*lang=([^&]+)") {set $new_args "id=$1&lang=$2";
rewrite ^(.*)$ $1?$new_args? last;
}
(末尾两个 ?:第一个表示拼接新参数,第二个表示不继承原参数)
推荐用于中等以上复杂度场景。map 在 server 级定义,无执行顺序依赖,避免 if 的已知限制。
server 块外(通常放在 http 块)定义映射:
map $args $target_path {default "";
~*id=(d+) "/article/$1";
~*cat=([a-z]+) "/category/$1";
}
location / {if ($target_path) {
rewrite ^ $target_path? last;
}
}
注意结尾的 ? 表示清除原始参数,只保留重写后路径自带的(如有)
有时只需删掉某个参数(如 tracking 类),不改变路径。
set 清空 $args 再重建:
if ($args ~ "ref=[^&]*") {set $args $args;
rewrite ^(.*)$ $1? break;
}
这不行——$args 是只读别名?不对,$args 可写,但正则替换需更精细
map 构造干净参数串,或搭配 perl_set(需编译支持)。更实用的是用 try_files + 内部重定向规避参数传递,或交由后端处理绕不开的几个点,配错就失效:
$uri 是 /search,$args 才是 q=nginx
ID=123 要用 ~* id=,否则漏掉