如何为RewriteRule添加条件,排除子目录中不存在的文件?
问题原因
你当前配置里的「强制URL末尾加斜杠」规则的文件存在性判断逻辑有缺陷,子路径场景下会错误触发重定向。原判断%{REQUEST_FILENAME}.php -f在处理多层路径时,会基于磁盘物理路径做匹配,无法准确识别当前请求的路径对应的PHP文件是否真实存在,导致不存在的子路径也被加上了末尾斜杠。
修改方案
第一步:关闭内容协商避免误判
在Options配置项新增-MultiViews,关闭Apache的自动内容协商功能,避免它自动匹配路径导致规则异常。
第二步:调整加斜杠规则的判断条件
将原加斜杠规则的文件存在性判断改为基于请求URI的全路径匹配,只有当请求路径对应的PHP文件真实存在时,才触发加斜杠重定向,否则直接跳过规则。同时给内部转发规则也补充文件存在性判断,避免无效路径转发报错。
修改后的完整.htaccess配置
# Redirects for errors ErrorDocument 404 /error.php ErrorDocument 403 /error.php # Hides directory file listings + 关闭内容协商 Options -Indexes -MultiViews # Turn mod_rewrite on RewriteEngine On RewriteBase / # Force slash at end of URL (仅当对应PHP文件存在时才加斜杠) RewriteCond %{REQUEST_URI} /+[^\.]+$ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L] # To externally redirect /dir/foo.php to /dir/foo RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC] RewriteRule ^ %1 [R=301,L] # To internally forward /dir/foo to /dir/foo.php RewriteCond %{SCRIPT_FILENAME} !-d RewriteCond %{DOCUMENT_ROOT}/$1.php -f RewriteRule ^([^.]+)/$ $1.php [NC,L]
注意事项
修改后需要清空浏览器缓存再测试,因为原有301永久重定向会被浏览器缓存,可能导致测试结果不准。
内容的提问来源于stack exchange,提问作者R Barnes
相关产品推荐
相关产品推荐

