目录
为什么要清空查询参数
查询参数(query string)是URL中问号后面的部分,比如 ?id=123&from=google。在实际运维中,你经常需要把这些参数干掉:
- 清除追踪参数:UTM参数、fbclid、gclid等营销追踪码,影响缓存命中率
- 去掉多余参数:分页参数page、排序参数sort在重定向后不再需要
- 安全考虑:token、sessionid等敏感信息不应出现在重定向后的URL中
- SEO规范化:不同参数组合产生重复页面,搜索引擎会降权
下面4种方法,从简单到高级,覆盖所有场景。
方法一:rewrite带问号完全清空
这是最直接的方式——在rewrite目标URL末尾加一个问号,Nginx会丢弃所有原始查询参数。
基础写法
server {
listen 80;
server_name example.com;
# 所有请求重定向到HTTPS,清空查询参数
if ($scheme = http) {
rewrite ^ https://$host$request_uri? permanent;
}
}
工作原理
关键在于末尾那个 ?。在Nginx rewrite规则中:
rewrite ^ /new-url→ 原参数保留,Nginx自动拼接$is_args$argsrewrite ^ /new-url?→ 原参数全部丢弃,因为问号覆盖了$argsrewrite ^ /new-url?$args→ 手动控制参数,保留原参数
适用场景
适合需要一刀切清空参数的情况,比如网站迁移时丢弃所有旧参数。
注意事项
使用 return 301 时同样可以清空参数:
# return方式清空参数(URL末尾加?)
return 301 https://$host$request_uri?;
但要注意:如果 $request_uri 本身没有查询参数,加上 ? 后URL末尾会多出一个问号,比如 https://example.com/path?。多数情况下无害,但追求干净可以用 $uri 替代。
方法二:set清空$args变量
通过 set 指令把 $args 变量置空,适合在处理过程中逐步清除参数。
配置示例
location /clean {
# 清空所有查询参数
set $args '';
rewrite ^ /target permanent;
}
进阶用法:先处理再清空
location /api {
# 先保存需要的参数值
set $id $arg_id;
# 清空所有参数
set $args '';
# 用保存的值重新构建URL
rewrite ^ /new-api/$id? permanent;
}
适用场景
当你需要先提取某些参数值,再清空全部参数时,用set方法最灵活。
方法三:正则匹配选择性删除指定参数
这是实战中最常用的方式——只删掉特定的参数,保留其他参数。
核心思路
用正则表达式从 $args 中剔除不需要的参数,然后重新赋值。
删除单个参数(如utm_source)
location / {
# 匹配并删除utm_source参数
if ($args ~* "(^|&)utm_source=[^&]*") {
set $args $1$2;
rewrite ^(.*)$ $1? permanent;
}
}
删除多个追踪参数
location / {
# 逐步删除UTM五件套
if ($args ~* "(^|&)utm_source=[^&]*&?(.*)") {
set $args $1$2;
}
if ($args ~* "(^|&)utm_medium=[^&]*&?(.*)") {
set $args $1$2;
}
if ($args ~* "(^|&)utm_campaign=[^&]*&?(.*)") {
set $args $1$2;
}
if ($args ~* "(^|&)utm_content=[^&]*&?(.*)") {
set $args $1$2;
}
if ($args ~* "(^|&)utm_term=[^&]*&?(.*)") {
set $args $1$2;
}
# 如果还有参数残留,触发重定向
if ($args != '') {
return 301 $scheme://$host$uri?$args;
}
}
更简洁的写法(单次正则)
# 删除所有utm_开头的参数
if ($args ~ "(^|&)utm_[^&=]+=[^&]*(?:&|$)") {
set $cleaned_args $args;
# 循环清除直到没有utm_参数
set $iter "";
clean_utm:
if ($cleaned_args ~ "(^|&)utm_[^&=]+=[^&]*(?:&(.*)|$)") {
set $cleaned_args $1$2;
set $iter "x";
}
if ($iter != "") {
rewrite ^(.*)$ $scheme://$host$1?$cleaned_args? last;
}
}
适用场景
适合精准打击——只删特定参数,不影响其他参数。CDN缓存规范化、安全清理、SEO去重都用这个。
方法四:map指令按条件过滤参数
map指令可以在server级别定义参数过滤规则,然后在location中应用,配置更优雅、可维护。
配置示例
# 在http块中定义map规则
map $args $filtered_args {
default $args;
"~^(.*)(&?)utm_source=[^&]*" "$1$2";
"~^(.*)(&?)utm_medium=[^&]*" "$1$2";
"~^(.*)(&?)utm_campaign=[^&]*" "$1$2";
"~^(.*)(&?)fbclid=[^&]*" "$1$2";
"~^(.*)(&?)gclid=[^&]*" "$1$2";
}
server {
listen 443 ssl;
server_name example.com;
location / {
# 如果过滤后的参数和原始不同,301重定向到干净URL
if ($filtered_args != $args) {
rewrite ^(.*)$ $scheme://$host$1?$filtered_args? redirect;
}
# 正常处理请求
proxy_pass http://backend;
}
}
map方法的优势
- 声明式配置:所有过滤规则集中定义,一目了然
- 可扩展:新增要删除的参数只需加一行map规则
- 零if嵌套:避免if多层嵌套导致的配置复杂
注意事项
map的匹配是按顺序的,后面的规则会基于前面规则的输出继续匹配。所以要确保规则的顺序合理,避免前面的规则影响后面的匹配。
4种方法对比总结
| 方法 | 语法 | 清空范围 | 适用场景 | 复杂度 |
|---|---|---|---|---|
| rewrite带? | rewrite ^ /url?; | 全部参数 | 一刀切清空 | ★☆☆☆☆ |
| set清空 | set $args ''; | 全部参数 | 先提取再清空 | ★★☆☆☆ |
| 正则删除 | if + set $args | 指定参数 | 精准删除 | ★★★☆☆ |
| map过滤 | map + if | 指定参数 | 批量规范化 | ★★★☆☆ |
常见踩坑
坑1:清空后URL末尾多一个问号
用 rewrite ^ /path? 后,如果原URL没有参数,重定向后URL变成 /path?,末尾多了一个问号。
解决:用 $uri 替代 $request_uri($uri不含参数),或者用 $is_args 判断是否需要问号。
坑2:if块中set $args不生效
在某些Nginx版本中,if块内的 set $args 可能不生效。
解决:升级Nginx版本,或在server块层面使用map替代if。
坑3:正则删除导致参数残留&号
删除中间参数后,URL可能变成 ?a=1&&b=2,出现连续的&号。
解决:在正则中同时匹配参数后的&号,或最后用sed二次清洗。
坑4:map匹配顺序导致参数删除不彻底
多个map规则如果匹配顺序不对,可能漏删参数。
解决:确保每个map规则独立完整,或使用更精确的正则。
总结
清空Nginx查询参数的核心在于理解rewrite末尾问号的行为和 $args 变量的可控性。简单场景用问号,复杂场景用map,这是最稳妥的策略。如果只需要删除特定参数,正则匹配+set组合是最灵活的方案。实际部署前,务必用curl命令验证重定向后的URL是否符合预期。
相关文章
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论