rewriterule 本身不直接过滤动态参数,需配合 rewritecond 判断 query_string 实现参数控制、拦截、重写或标记;常见用法包括限制合法参数、屏蔽危险关键词、提取参数重写、qsa 保留参数及设置环境变量。

Apache 的 RewriteRule 本身不直接“过滤”动态参数,而是通过配合 RewriteCond(条件判断)和正则捕获,实现对含特定参数的请求进行识别、重写、跳过或拦截。真正起过滤作用的是条件匹配逻辑,不是规则本身。
用 RewriteCond 检查 QUERY_STRING 实现参数控制
URL 中的查询参数(如 ?id=123&sort=desc&token=abc)属于 %{QUERY_STRING} 变量,需用 RewriteCond 判断,再决定是否触发后续 RewriteRule:
-
只允许合法参数:例如仅接受
id和page,其余一律拒访RewriteCond %{QUERY_STRING} !^(id=[0-9]+&)?page=[0-9]+$<br>RewriteRule ^/list\.php$ - [F] -
屏蔽含危险参数的请求:比如过滤掉
exec、cmd、phpinfo等关键词RewriteCond %{QUERY_STRING} (exec|cmd|system|phpinfo|base64_decode) [NC]<br>RewriteRule ^.*$ - [F] -
提取并重写特定参数组合:如把
/product.php?id=100&name=phone转成/product/100/phoneRewriteCond %{QUERY_STRING} ^id=([0-9]+)&name=([^&]+)$<br>RewriteRule ^/product\.php$ /product/%1/%2? [R=301,L]
注意末尾的?用于清空原始查询字符串。
用 RewriteRule + QSA 保留/合并参数
当需要在重写后仍携带部分原始参数(如跟踪参数 utm_source),用 [QSA] 标志自动追加:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 原始请求:
/article/123?utm_medium=email&ref=share - 规则:
RewriteRule ^article/([0-9]+)$ /article.php?id=$1 [QSA,L,NC] - 实际转发:
/article.php?id=123&utm_medium=email&ref=share
这样既完成了路径美化,又没丢掉分析所需参数。
用环境变量或内部标记做轻量级参数处理
不改变 URL,仅对含某参数的请求打标,供后续模块(如日志、PHP)识别:
- 给带
debug=1的请求设置环境变量:RewriteCond %{QUERY_STRING} (^|&)debug=1(&|$)<br>RewriteRule ^ - [E=DEBUG:1] - PHP 中可通过
$_SERVER['REDIRECT_DEBUG']或getenv('DEBUG')获取该标记。
常见陷阱与避坑提醒
写参数相关规则时容易出错的地方:
-
QUERY_STRING 不含 ?:匹配时写
^id=123$,不是^\?id=123$ - 顺序很重要:RewriteCond 只对其后紧邻的一条 RewriteRule 生效;多条规则需重复写 Cond
- 不要漏掉 L 标志:否则可能被后续规则二次处理,导致循环或意外覆盖
-
区分重定向(R)和内部重写(无 R):过滤恶意参数建议用
[F]或[G]直接拦截,而非跳转










