Apache中匹配查询字符串须用%{QUERY_STRING}变量,其值为?后原始编码内容,正则需按编码形式编写,配合RewriteRule时需显式引用或使用QSA/QSD标志。

Apache 的 RewriteCond 匹配查询字符串(即 URL 中 ? 后面的部分),需要用 %{QUERY_STRING} 变量,不能用 %{REQUEST_URI} 或 %{REQUEST_FILENAME}。
基本写法:用 %{QUERY_STRING} 配合正则匹配
%{QUERY_STRING} 获取的是完整的查询字符串,不含开头的 ?。例如请求 /page.php?id=123&cat=tech,%{QUERY_STRING} 的值就是 id=123&cat=tech。
常见写法示例:
- 匹配包含
id=123(顺序无关,且允许前后有其他参数):RewriteCond %{QUERY_STRING} id=123 - 精确匹配整个查询字符串为
id=123:RewriteCond %{QUERY_STRING} ^id=123$ - 匹配
id参数值为纯数字(如id=456,但不匹配id=abc):RewriteCond %{QUERY_STRING} ^id=[0-9]+$ - 匹配存在
ref=参数(值任意):RewriteCond %{QUERY_STRING} ref=
注意 URL 编码和特殊字符处理
查询字符串中可能出现 URL 编码(如空格变 + 或 %20,中文变 %E4%B8%AD 等)。正则默认按编码后形式匹配。
例如请求 /search?q=hello world → 实际 QUERY_STRING 是 q=hello+world 或 q=hello%20world,需按实际编码写正则:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 匹配带空格的搜索词(兼容
+和%20):RewriteCond %{QUERY_STRING} q=([^&]*[+%20][^&]*) - 更稳妥的做法是先解码再匹配——但 Apache 的
RewriteCond默认不自动解码,所以建议在规则逻辑中尽量避免依赖未解码内容,或改用后端处理。
配合 RewriteRule 使用的典型场景
匹配到查询字符串后,通常用于重写或跳转。注意:QUERY_STRING 不会自动带入新 URL,需显式用 %{QUERY_STRING} 或 [QSA] 标志保留。
- 把含
debug=1的请求重写到调试页面:RewriteCond %{QUERY_STRING} debug=1RewriteRule ^(.*)$ /debug.php?%{QUERY_STRING} [L] - 去掉
utm_source参数并 301 跳转(保留其余参数):RewriteCond %{QUERY_STRING} ^(.*)&utm_source=[^&]+&(.*)$RewriteRule ^(.*)$ /$1?%1%2 [R=301,L]
或更简洁地用[QSD](Apache 2.4+)清除整个 QS,再手动拼接。 - 常用技巧:用
[QSA](Query String Append)自动追加原查询参数:RewriteCond %{QUERY_STRING} campaign=testRewriteRule ^/old\.php$ /new.php [QSA,L]→ 请求/old.php?campaign=test&id=7会变成/new.php?campaign=test&id=7
调试小技巧
QUERY_STRING 匹配容易出错,推荐开启重写日志(Apache 2.4 推荐用 RewriteLogLevel + RewriteLog 已废弃,改用 LogLevel alert rewrite:trace3)来查看每次匹配过程。
简单验证方法:临时写一条规则把 QUERY_STRING 输出到响应头或重定向 URL 中,比如:
-
RewriteCond %{QUERY_STRING} .+RewriteRule ^test$ /echo?qs=%{QUERY_STRING} [R,L]→ 访问/test?foo=bar会跳转到/echo?qs=foo=bar










