Apache htaccess正则匹配非斜杠路径时出现重定向循环报错
问题根因
循环触发的核心原因是修改后的正则^[^/]+$覆盖匹配了重写目标page.html本身。
.htaccess属于目录级重写上下文,mod_rewrite在此场景下的执行逻辑是:当规则把原请求(比如/abc)重写到page.html后,Apache会把重写后的路径作为新的待处理请求,重新从头走一遍所有重写规则。由于page.html完全符合「不包含/的单段路径」的匹配规则,会被再次重写到page.html,反复迭代直到触发Apache默认的10次内部重定向上限,抛出500错误。
之前的规则没有触发循环,是因为正则仅匹配abc/bca/cab三个固定路径,page.html不在匹配范围内,重写后的二次匹配不会命中规则,流程自然终止。
补充说明:加[L]标记没有生效,是因为[L]的作用仅为终止当前轮次的重写规则执行,不会阻止重写后的请求重新进入完整重写流程开启下一轮匹配,这是很多使用者对[L]标记的常见误解。
解决方案
根据实际场景选以下任意一种即可:
- 通用方案(推荐):增加条件排除服务器上真实存在的文件/目录,适配后续规则扩展
当重写后的# 待匹配路径不是真实存在的文件时才执行重写 RewriteCond %{REQUEST_FILENAME} !-f # 待匹配路径不是真实存在的目录时才执行重写 RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^[^/]+$ page.html [L]page.html进入第二轮匹配时,会因为是真实存在的文件不满足前置条件,规则不会触发,直接切断循环。 - 精准匹配方案:如果不需要重写真实存在的静态资源,直接在正则中排除目标文件
该方案不需要额外判断文件存在性,性能略高,适合规则固定的场景。# 负向预查直接排除page.html本身 RewriteRule ^(?!page\.html$)[^/]+$ page.html [L] - 终止流程方案(Apache 2.4+可用):用
[END]标记替代[L]标记RewriteRule ^[^/]+$ page.html [END][END]标记会直接终止整个重写流程,不会启动后续轮次的规则匹配,从机制上避免循环。注意如果规则链中还有其他需要在重写后执行的逻辑,不要用该方案,避免打断正常规则执行。
内容的提问来源于stack exchange,提问作者treekt
相关产品推荐
相关产品推荐

