.htaccess递归斜杠转下划线内部重定向规则突然失效求解
问题根源定位
- 核心触发为CentOS 8近期推送的Apache安全补丁修复了
mod_rewrite模块对REQUEST_FILENAME的实时计算逻辑,原有配置的规则执行顺序错误,此前依赖的模块bug被修复后直接失效 - 原有配置中404校验规则位于斜杠转下划线规则之前,每次
[N]触发递归重写时,中间路径(如/this_is/mah/page/structure)会被判定为不存在文件/目录、对应PHP文件也不存在,直接触发404中断递归流程 - 原有配置中提前追加
.php后缀的规则位于替换规则之前,会对未完成斜杠替换的路径直接追加后缀,阻断后续替换逻辑 - 冗余的单斜杠兜底规则无存在必要,统一由递归规则处理所有路径格式
修正后可直接运行的.htaccess配置
<IfModule mod_negotiation.c> Options -MultiViews Options All -Indexes </IfModule> <IfModule mod_rewrite.c> RewriteEngine on # 限制最大递归循环次数,避免异常路径导致死循环 RewriteOptions MaxRedirects=10 DirectorySlash off # 自定义404页面 ErrorDocument 404 /incs/404.php # 前置递归转换:将路径中所有斜杠替换为下划线 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^/]+)/(.+)$ $1_$2 [N,DPI] # 对外跳转:移除URL中的.php后缀 RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC] RewriteRule ^ /%1 [R=301,NE,L] # 内部映射:为已存在的PHP文件追加后缀 RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^([^.]+?)/?$ $1.php [L] # 最终兜底404校验 RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME}.php !-f RewriteRule ^ - [R=404,L] </IfModule>
配置运行逻辑说明
- 规则顺序调整为「先完成路径格式转换 → 再处理对外跳转 → 最后追加PHP后缀做内部映射 → 兜底404」,完全规避原有规则的前置拦截问题
- 递归替换规则简化为通用匹配逻辑,只要路径中存在斜杠就替换首个斜杠为下划线,通过
[N]标记自动循环直到路径无斜杠,无需单独处理单斜杠的兜底逻辑 - 内部映射环节新增
RewriteCond %{REQUEST_FILENAME}.php -f校验,仅当对应PHP文件真实存在时才追加后缀,避免无效映射 - 原有的目录索引禁止、多视图关闭、自定义错误页面等功能全部保留
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

