qsa标志用于在apache mod_rewrite中合并新参数与原始查询字符串。当rewriterule目标含“?”时,需显式添加[qsa]才能保留原始参数;否则原始query string会被覆盖。

QSA(Query String Append)标志是 Apache mod_rewrite 中处理查询参数的关键机制,它解决的核心问题是:在重写或重定向时,既添加新参数,又不丢失原始 URL 中的 query string。
QSA 的作用原理
Apache 的 RewriteRule 默认只匹配 URI path(如 /search/term),完全不涉及 ? 后面的查询字符串(如 ?page=2&sort=date)。所以当你写:
RewriteRule ^search/([^/]+)$ /search.php?q=$1 [R,L]
浏览器跳转后,原始 ?page=2 会自动保留——这是默认行为,无需 QSA。但一旦你在目标地址中手动写了 ?,比如:
RewriteRule ^search/([^/]+)$ /search.php?q=$1&src=apache [R,L]
这时原始参数就会被整个覆盖。QSA 的作用,就是让手动添加的参数与原始参数自动合并成一个完整的 query string。
正确使用 QSA 的写法
必须同时满足两个条件:
- 目标 Substitution 中包含 ?(即显式定义了新参数)
- 规则末尾明确加上 [QSA] 标志(可与其他标志如 R、L 并列)
例如:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
RewriteRule ^product/(\d+)$ /product.php?id=$1&utm_source=rewrite [QSA,R=302,L]
若原始请求是 /product/123?ref=blog&lang=zh,重定向后地址为:
/product.php?id=123&utm_source=rewrite&ref=blog&lang=zh
注意:QSA 总是把原始 query string 追加在你写的参数之后,顺序固定,不可调整。
常见错误与规避方式
以下写法会导致参数丢失或行为异常:
- 在 .htaccess 中误加开头斜杠:写成 ^/product/(\d+)$ → 实际应为 ^product/(\d+)$
- 忘记开启重写引擎:RewriteEngine On 必须出现在每段规则前(尤其在多个
或 .htaccess 中) - AllowOverride 未设为 All:虚拟主机配置中若设了 AllowOverride None,.htaccess 将完全失效
- 用 [R=301] 测试时被浏览器缓存:首次调试务必用 [R=302],确认无误再换 301
需要捕获原始参数时用 RewriteCond
QSA 只负责“追加”,不负责“读取”或“判断”。如果你想根据 query string 内容做不同处理(比如有 phone 参数才跳去 myaction_phone),就得配合 RewriteCond:
RewriteCond %{QUERY_STRING} ^phone=(\d+)$
RewriteRule ^/$ /default/myaction_phone?company=1 [QSA,R,L]
这里 %{QUERY_STRING} 是服务器变量,代表 ? 后全部内容;正则捕获的 $1 可在后续规则中引用(但不能直接用于 Substitution 中的 ? 后面,需靠 QSA 传递)。









