Apache RewriteRule 不支持动态变量拼接,需通过 RewriteCond 捕获变量(%1等)、RewriteRule 中混用 $N/%N/%{VAR} 并配合 QSA[L] 等标志分步实现重定向。

Apache 的 RewriteRule 本身不支持“动态变量组合”这种编程式拼接,比如不能像 PHP 那样写 $host . '/api/v' . $version . '/' . $id。它靠的是正则捕获 + 条件判断 + 标志协同,在规则链中分步提取、传递、拼接。真正实现复杂重定向目标,关键不是单条规则多花哨,而是用好 RewriteCond 捕获变量、用好 %{VAR} 引用、再通过 [QSA] 或手动拼接控制输出。
用 RewriteCond 提前捕获关键变量
URL 路径、查询参数、请求头、主机名这些信息,必须用 RewriteCond 单独提取,不能指望一条 RewriteRule 吃下全部:
- 捕获子域名:
RewriteCond %{HTTP_HOST} ^([a-z0-9\-]+)\.example\.com$ [NC]→ 可用%1引用 - 捕获查询参数:
RewriteCond %{QUERY_STRING} version=([^&]+)→ 可用%1引用 - 捕获路径段:
RewriteCond %{REQUEST_URI} ^/v(\d+)/user/(\d+)→%1是版本号,%2是用户 ID - 组合使用时注意顺序:多个
RewriteCond默认是 AND,所有条件都满足才触发后续RewriteRule
在 RewriteRule 中安全拼接目标 URL
Substitution(替换目标)里可混用:$N(来自 Rule 的正则捕获)、%N(来自最后一条匹配的 Cond)、%{VAR}(服务器变量),但要注意作用域和转义:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 基础拼接示例(带版本分流):
RewriteCond %{HTTP_HOST} ^api\.example\.com$<br> RewriteCond %{REQUEST_URI} ^/v(\d+)/products/(\d+)<br> RewriteRule ^ /api-backend/v%1/products.php?id=%2 [L,QSA]
→ 把/v2/products/456映射到/api-backend/v2/products.php?id=456 - 跨域重定向(含协议+主机+路径+参数):
RewriteCond %{HTTP_HOST} ^old\.example\.com$<br> RewriteCond %{REQUEST_URI} ^/blog/(.*)<br> RewriteCond %{QUERY_STRING} ^(.*)$<br> RewriteRule ^ https://new.example.com/articles/%1?%1 [R=301,L,NE]
→ 注意[NE]防止 ? 和 & 被二次编码;%1来自 REQUEST_URI,第二个%1来自 QUERY_STRING
避免常见陷阱:变量覆盖、循环、编码错误
多条件或多规则下,变量引用极易出错,尤其当多个 RewriteCond 都匹配时,%1 总是指向最后一条成功匹配的条件:
- 不要依赖“第几个条件”的直觉:始终把最想用的变量放在最后一个
RewriteCond,或拆成独立规则链 - 防止无限重定向:确保重写后的目标路径不再匹配原规则,加
[L]终止,或用!-f/!-d排除真实文件目录 - 中文或特殊字符要小心:默认会 URL 编码,如需保留原始形态,加
[NE];但后端脚本也要能正确解析 - 调试建议:开发期用
[R=302]替代[R=301],避免浏览器缓存掩盖问题;Apache 2.4+ 可启用LogLevel alert rewrite:trace3查日志
不复杂但容易忽略。核心就三点:条件先抓准、引用分清 $ 和 %、拼接时加对标志。写完别急着上线,用 curl -I 看响应头,确认是 200 还是 301,地址栏变没变,参数传过去没。

















