问题描述
AddDefaultCharset UTF-8
#
# page.PHP
#
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^page/([^.]+)?$ page.PHP?slug=$1 [L,NC,QSA]
最近几个月,这个简单的规则在某些服务器(cPanel 和 VirtualMin)中不起作用,并且不明白问题出在哪里。
规则匹配并执行位于 public_html 但 slug 变量为空的 page.PHP 脚本。
我发现,如果我将 page.PHP 重命名为 _page.PHP,它可以正常工作。
为了更清楚
如果粗体匹配,我就没有 slug
page/([^.]+)?$ page.PHP?slug=$1
如果我使用
_page/([^.]+)?$ page.PHP?slug=$1
page/([^.]+)?$ _page.PHP?slug=$1
page/([^.]+)?$ page99.PHP?slug=$1
一切正常。
当然我有其他规则可以正常工作。只有这条规则失败了。
感谢任何帮助
解决方法
看起来可能在这些服务器上启用了 MultiViews,但它不起作用(即 slug
URL 参数丢失)。
在 .htaccess
文件顶部禁用多视图:
Options -MultiViews
默认 Apache 安装中禁用了 MultiViews,但是,某些共享主机出于某种原因在服务器配置中启用了此功能。
MultiViews 基本上支持开箱即用的无扩展 URL。当启用 MultiViews 并且您请求 /page
(或 /page/<something>
)时,mod_negotiation 会查找映射到相同基本名称(即 page
)的资源,该资源将返回适当的 MIME 类型(即text/html
)。换句话说,它会查找 page.php
或 page.html
等形式的文件。这发生在 mod_rewrite 能够处理请求之前,因此 URL 参数(在您的 mod_rewrite指令)丢失,因为 RewriteRule
没有得到处理(不匹配)。
我发现如果我将 page.php
重命名为 _page.php
,它工作正常。
是的,因为请求的 URL page
未映射到物理文件的基本名称。