如何配置Apache mod_rewrite使用L标志位有效终止多余规则循环处理?
- 内容介绍
- 文章标签
- 相关推荐
本文共计813个文字,预计阅读时间需要4分钟。
L 标志本身体不阻止重定向循环,它只停止当前请求周期内的重定向规则匹配;真正的循环发生在浏览器收到 R(重定向)响应后,如果发生新的请求,Apache 会将这当作一个全新的请求重新走一遍所有规则——L 对这个新请求无效。
为什么加了 [L] 还会死循环
典型场景是这类规则:
RewriteRule ^(.*)$ /111/$1 [R,L]
浏览器访问 /index.html → 302 跳转到 /111/index.html → 浏览器再发请求 → Apache 再次匹配 ^(.*)$ → 又跳到 /111/111/index.html,无限套娃。
[L] 确实让这条规则后面不再执行,但它不阻止重定向触发的新请求被再次捕获。关键点在于:R 和 L 是两件事:前者发 HTTP 响应,后者仅控制本周期规则链。
-
R触发外部跳转,浏览器参与进来 -
L只作用于当前内部处理流程,对下一次请求无约束力 - 没有
RewriteCond排除已重写路径,规则就会反复命中
RewriteCond 必须配合 RewriteRule 使用
真正终止循环的方式,是在规则前加条件判断,确保目标路径不被再次匹配。最常用的是检查 %{REQUEST_URI}:
RewriteCond %{REQUEST_URI} !^/111/<br>RewriteRule ^(.*)$ /111/$1 [R,L]
注意几个细节:
-
!^/111/中的!表示“不匹配”,必须写在条件开头 -
%{REQUEST_URI}是原始请求路径(如/test.php),不是重写后的 - 如果要排除多个路径,可用管道符:
!^(/111|/admin|/api) - 不要用
$1在RewriteCond里引用,它只在RewriteRule捕获后才有效
区分 [L] 和 [END] 的实际影响
[END] 是 Apache 2.4+ 引入的标志,它能彻底终止整个重写过程,包括后续子请求。但要注意:
-
[END]不能和R共存([R,END]会报错),它只适用于内部重写(无跳转) - 想做跳转又防循环,
RewriteCond+[R,L]是唯一可靠组合 - 若误用
[END]替代[L]且带R,Apache 会直接拒绝加载配置 - 旧版 Apache(2.2)根本不识别
[END],配置会失败
调试时最容易忽略的两个点
循环问题常因环境差异暴露不出来:
- 用
curl -I测试时可能只看到一次跳转,因为默认不跟随重定向;加-L才能复现真实浏览器行为 -
.htaccess中的规则受AllowOverride All控制,若配置为None或FileInfo不足,RewriteCond可能被静默忽略
本文共计813个文字,预计阅读时间需要4分钟。
L 标志本身体不阻止重定向循环,它只停止当前请求周期内的重定向规则匹配;真正的循环发生在浏览器收到 R(重定向)响应后,如果发生新的请求,Apache 会将这当作一个全新的请求重新走一遍所有规则——L 对这个新请求无效。
为什么加了 [L] 还会死循环
典型场景是这类规则:
RewriteRule ^(.*)$ /111/$1 [R,L]
浏览器访问 /index.html → 302 跳转到 /111/index.html → 浏览器再发请求 → Apache 再次匹配 ^(.*)$ → 又跳到 /111/111/index.html,无限套娃。
[L] 确实让这条规则后面不再执行,但它不阻止重定向触发的新请求被再次捕获。关键点在于:R 和 L 是两件事:前者发 HTTP 响应,后者仅控制本周期规则链。
-
R触发外部跳转,浏览器参与进来 -
L只作用于当前内部处理流程,对下一次请求无约束力 - 没有
RewriteCond排除已重写路径,规则就会反复命中
RewriteCond 必须配合 RewriteRule 使用
真正终止循环的方式,是在规则前加条件判断,确保目标路径不被再次匹配。最常用的是检查 %{REQUEST_URI}:
RewriteCond %{REQUEST_URI} !^/111/<br>RewriteRule ^(.*)$ /111/$1 [R,L]
注意几个细节:
-
!^/111/中的!表示“不匹配”,必须写在条件开头 -
%{REQUEST_URI}是原始请求路径(如/test.php),不是重写后的 - 如果要排除多个路径,可用管道符:
!^(/111|/admin|/api) - 不要用
$1在RewriteCond里引用,它只在RewriteRule捕获后才有效
区分 [L] 和 [END] 的实际影响
[END] 是 Apache 2.4+ 引入的标志,它能彻底终止整个重写过程,包括后续子请求。但要注意:
-
[END]不能和R共存([R,END]会报错),它只适用于内部重写(无跳转) - 想做跳转又防循环,
RewriteCond+[R,L]是唯一可靠组合 - 若误用
[END]替代[L]且带R,Apache 会直接拒绝加载配置 - 旧版 Apache(2.2)根本不识别
[END],配置会失败
调试时最容易忽略的两个点
循环问题常因环境差异暴露不出来:
- 用
curl -I测试时可能只看到一次跳转,因为默认不跟随重定向;加-L才能复现真实浏览器行为 -
.htaccess中的规则受AllowOverride All控制,若配置为None或FileInfo不足,RewriteCond可能被静默忽略

