apache mod_rewrite 通过环境变量(e=var:val)实现同请求内状态标记与传递,如[e=processed:1]设标记、%{env:processed}^1$判断,用于防重复跳转、条件启用规则等,零开销且原生支持。

Apache 的 mod_rewrite 本身不提供跨规则的“状态变量”机制,但可以通过环境变量(E=VAR:VAL)在同一次请求处理中实现标记传递——关键在于:环境变量一旦设置,就持续存在于该请求的整个生命周期内,后续的 RewriteCond 和 RewriteRule 都能读取它。
用环境变量做标记的核心逻辑
环境变量在这里不是为了传给后端,而是作为 Apache 内部的“轻量标记开关”。比如标记“这个请求已被某类规则处理过”,避免重复动作或触发分支逻辑。
- 用
[E=PROCESSED:1]设置一个存在即表示已处理的标记 - 后续规则用
RewriteCond %{ENV:PROCESSED} ^1$判断是否已标记 - 条件成立时执行特定操作(如跳过、改写、加头),不成立则走默认流程
常见实用场景示例
防止重复重定向:当多个规则都可能触发 301 跳转时,用环境变量确保只跳一次。
RewriteCond %{HTTP_HOST} ^old\.example\.com [NC]
RewriteRule ^(.*)$ https://new.example.com$1 [E=REDIRECTED:1,R=301,L]
<p>RewriteCond %{ENV:REDIRECTED} !^1$
RewriteCond %{REQUEST_URI} ^/legacy/
RewriteRule ^/legacy/(.*)$ /new-path/$1 [E=REDIRECTED:1,R=301,L]</p>
第二条规则仅在未被第一条标记时才执行,避免两个跳转叠加。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
按条件启用/禁用某组规则:比如仅对移动端用户激活特定重写。
RewriteCond %{HTTP_USER_AGENT} "iPhone|Android" [NC]
RewriteRule ^ - [E=MOBILE:1]
<p>RewriteCond %{ENV:MOBILE} ^1$
RewriteRule ^/product/(\d+)$ /m/product/$1 [L]</p><p>RewriteCond %{ENV:MOBILE} ^1$
RewriteRule ^/css/(.*)$ /m/css/$1 [L]</p>
所有移动端专用规则都依赖 %{ENV:MOBILE} 标记,统一开关,结构清晰。
注意事项与技巧
- 环境变量名建议全大写(如
IS_API),避免与系统变量冲突 - 值可以是任意字符串,常用
1、yes、skip等语义明确的标识 - 用
!^1$表示“未设置或不等于1”,比单纯检查是否存在更稳妥 - 环境变量在子请求(如内部重写后再次匹配)中仍保留,但不会跨请求持久化
- 若需清除标记,可用
RewriteRule ^ - [E=FLAG:]将其设为空字符串(注意冒号后无值)
这种方式不依赖外部存储,零额外开销,是 Apache 原生支持的、最简洁的状态传递方式。










