[L]标志使Apache在规则命中后立即终止当前轮次处理,跳过后续所有规则,避免冗余正则匹配和条件判断,尤其在50+规则场景下可降低30%以上开销。
加
[L]
不是为了“终止循环”,而是让某条规则命中后不再检查后续规则——这直接切断了大量无效的正则匹配和条件判断,从而避免看似“循环”实为“重复遍历”的性能浪费。
为什么没加 [L] 会引发无效重复计算
Apache 的 mod_rewrite 默认按顺序逐条执行所有 RewriteRule。即使第 3 条规则已把
改写成
,引擎仍会拿着这个新 URI 继续匹配第 4、5、6……直到最后一条规则。每条规则都要重新做正则编译、字符串匹配、RewriteCond 判断——哪怕这些规则本不该干预该请求。
典型低效场景:
静态资源(
)被前面规则放过,却仍要跑完全部 50 条规则
API 请求(
)已转发给
,却被后面 WordPress 的
再次捕获
重定向规则漏加 [L],导致跳转后浏览器发起新请求,服务器又从头跑一遍规则(表面像循环,实为两次独立匹配)
哪些位置必须加 [L] 来阻断无效路径
只要某条规则是“终点”,就该加 [L]——不是为了防止逻辑循环,而是明确告诉 Apache:“到这里为止,别再看了”。关键位置包括:
Apache 2.4.62
PHP中文网提供Apache 2.4.62 官方 tar.gz 源码包下载,通过源码编译安装,开发者能够灵活定制模块、优化性能并精准控制安装路径,满足多样化的业务需求。
下载
所有外部重定向规则,例如
所有内部重写终点,例如将请求交由前端控制器处理:
静态资源拦截,如
(
表示不改 URI,仅终止)
条件性拒绝或屏蔽,如防盗链:
常见错误:以为加了 [L] 就万无一失
[L] 只终止当前轮次,不阻止重写后 URI 触发新一轮匹配。比如:
错误写法:
→ /backend/index.php?r=xxx 可能又被下一条
捕获,造成二次重写或 404
更稳妥做法:
• 升级到 Apache 2.4.17+,改用
彻底终结(仅限 VirtualHost 配置)
• 或在关键规则前加环境变量防护:
,后续用
控制跳过
验证是否生效的小技巧
开启重写日志(Apache 2.4+):
在 VirtualHost 中添加:
和
观察日志中某请求是否只触发 2–3 条规则(而非全部),说明 [L] 已起效
若看到同一请求反复出现 “initial request” → “subrequest” → “initial request”,说明存在未被 [L] 或 [END] 截断的多轮匹配
/post/123/index.php?path=123/css/main.css/api/v1/usersapi.php^(.*)$ → index.phpRewriteRule ^/old-page\.html$ /new-page.html [R=301,L]RewriteRule ^(.*)$ /index.php?path=$1 [L,QSA]RewriteRule ^/(css|js|images)/(.*)$ - [L]-RewriteRule \.(jpg|png|gif)$ - [F,L]RewriteRule ^/api/(.*)$ /backend/index.php?r=$1 [L]RewriteCond %{REQUEST_FILENAME} !-f[END]RewriteRule ^/api/ - [E=API_HIT:1]RewriteCond %{ENV:API_HIT} !=1RewriteLogLevel 3RewriteLog "/var/log/apache2/rewrite.log"