我有一个 LAMP 堆栈。我使用以下 .htaccess 文件自动将请求映射到 .php 文件:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
因此如果我浏览http://example.com/asdf“asdf.php”文件将被加载。
但是,如果我创建一个同名的 .css 文件(即“asdf.css”),那么当浏览到没有扩展名的名称时,服务器将返回 css 文件而不是 PHP 文件。对于 .txt 文件扩展名,以及任何其他三个字符的扩展名,似乎也会发生这种情况(尽管 .js 文件不会发生这种情况)。
我不明白为什么会发生这种情况。我对重写规则集的理解是:1) 如果请求的文件不存在,则 2) 如果文件名不包含句点,则将请求重定向到 [filename].php
这怎么可能返回 .txt 或 .css 文件,尤其是当匹配的 .php 文件存在时?我在这里遗漏了什么?
谢谢!
答案1
如果你有多个文件具有相同的基名,那么听起来你可能与 有冲突MultiViews
。尝试在.htaccess
文件(或服务器配置)中禁用此功能:
Options -MultiViews
MultiViews
(mod_negotiation 的一部分)执行的操作与您尝试使用 mod_rewrite 执行的操作相同,我怀疑它“成功了”。当您请求/asdf
并asdf
映射到文件基名时,MultiViews
它会尝试提供与预期 mime 类型匹配的适当文件(这可以解释为什么.js
文件会丢失)。
我对重写规则集的理解是:1)如果请求的文件不存在,则2)如果文件名不包含句点,则将请求重定向到[filename] .php
否则,你对 mod_rewrite 指令的理解基本正确,只是顺序相反(RewriteRule
图案被首先处理)...
- 如果 URL(即整个 URL)不包含句点。
- 并且请求没有映射到有效文件(如果所有文件都有文件扩展名则不太可能 - 因此可以省略这种情况)。
- 通过附加扩展来内部重写请求
.php
。
RewriteRule ^([^\.]+)$ $1.php [NC,L]
没有必要在字符类中转义文字句点,并且NC
这里的标志是多余的。