为何我的.htaccess规则被覆盖?CMS重写失效问题咨询
为什么你的CMS重写规则没生效?
核心问题出在规则匹配的路径范围和你实际访问的路径不匹配:
你配置的CMS规则是:
RewriteRule ^cms/$ /cms/administrator/index.php [L]
这个规则的^cms/$模式只匹配末尾带斜杠的请求——也就是website.nl/cms/这种格式。但你实际访问的是website.nl/cms(不带末尾斜杠),这个路径根本不会被这条规则捕获,所以请求会继续往下执行,直到被后面的分类列表规则命中。
后面的这条规则:
RewriteRule ^([\w-]+)/?$ catlisting.php?alias=$1 [QSA,L]
^([\w-]+)/?$的意思是“匹配任意由字母、数字、下划线、连字符组成的单个词,末尾斜杠可选”,cms完全符合这个模式,所以就被跳转到catlisting.php了。
额外补充:如果cms是服务器上真实存在的物理目录,正常情况下Apache会自动把/cms重定向到/cms/(带斜杠),但可能你的服务器配置里DirectorySlash被关闭了,或者.htaccess里的其他规则干扰了这个默认行为,导致没有自动补全斜杠,才让问题暴露出来。
怎么修复这个问题?
有两种简单的方式可以解决,选哪种看你的需求:
方案1:直接修改CMS规则,兼容带/不带斜杠的请求
把CMS规则改成下面这样,让末尾斜杠变成可选的:
#CMS rewrite RewriteRule ^cms/?$ /cms/administrator/index.php [L]
这里的/?表示“匹配0个或者1个斜杠”,这样不管你访问/cms还是/cms/,都会被这条规则捕获,而且[L]标记会让Apache停止执行后续规则,直接跳转到后台页面。
方案2:先强制给目录添加斜杠(适合cms是真实目录的场景)
如果cms是真实存在的物理目录,你可以先加一条规则,强制把不带斜杠的目录请求重定向到带斜杠的版本,再执行后台跳转:
# 强制给真实目录补全末尾斜杠 RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^(.*[^/])$ /$1/ [L,R=301] #CMS rewrite RewriteRule ^cms/$ /cms/administrator/index.php [L]
这种方式既解决了当前的后台跳转问题,还能避免因为同一目录的两种访问格式(带/不带斜杠)导致的SEO重复内容问题,一举两得。
验证修改效果
改完.htaccess之后,不管访问website.nl/cms还是website.nl/cms/,都应该直接跳转到你的CMS后台,不会再触发分类列表的规则了。
内容的提问来源于stack exchange,提问作者twan

