首先匹配文件而不是.htaccess规则

时间:2017-01-05 14:12:03

标签: php .htaccess mod-rewrite url-rewriting

每当我的网络服务器中有一个文件并在我的.htaccess中为同一路径重写规则时,该规则将被忽略并自动提供该文件。

我的网络服务器的public_html只有一个文件 - test.php,如下所示:

<?php
echo "hello ".$_GET['action']
?>

最初我的.htaccess为空,因此访问http://<domain-name>/test.php?action=world按预期回复hello world。我的webhost也是这样配置的,访问/test?action=world(空.htaccess)也与你的世界呼应。

现在我在.htaccess中添加以下public_html

RewriteEngine On
RewriteRule ^test/(\w+)$ test.php?action=$1 [NC,L]

我希望访问/test/world会回复hello world,但这不会发生!我在回复中只得到hello。现在我最初认为mod_rewrite未启用,因此要测试我将.htaccess更改为:

RewriteEngine On
RewriteRule ^testmod/(\w+)$ test.php?action=$1 [NC,L]

现在我惊讶地访问/testmod/world实际上回应了hello world!这表明mod_rewrite确实可用,并确认当请求的URL实际存在文件时忽略重写规则。

我的心智模型是Apache通过.htaccess中的规则,对于与所请求规则匹配的任何重写规则,Apache内部重定向到规则中指定的路径。但这确实发生在这里。看起来它首先检查是否存在所请求URL的任何文件,如果不存在,则查看重写规则。或者其他事情在这里发生,也许是因为我的webhost的配置? (仅供参考,我使用Bluehost作为我的虚拟主机)。

1 个答案:

答案 0 :(得分:1)

添加此项以禁用MultiViews:

Options -MultiViews

Apache docs on mod_negotiation描述了多视图选项启用时的功能:

  

如果   服务器接收/ some / dir / foo的请求和/ some / dir / foo没有   存在,然后服务器读取目录查找所有命名的文件   foo。*,并有效地伪造了一个类型地图,列出了所有这些   文件,为它们分配相同的媒体类型和内容编码   如果客户通过名字要求其中一个,那就会有。然后呢   选择与客户要求的最佳匹配,并返回   文档。

使用:

Options -MultiViews
RewriteEngine On
RewriteRule ^test/(\w+)$ test.php?action=$1 [NC,L]