我的 .htaccess 看起来像这样:
Options -Indexes
RewriteEngine On
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.html [L]
如果我访问 www.myhost.com,我会收到 302 Moved Temporarily 响应,将我重定向到 www.myhost.com/index.html。
如果我像这样注释掉 .htaccess 文件的某一特定行:
Options -Indexes
RewriteEngine On
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-f
#RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.html [L]
我访问 www.myhost.com,收到 200 OK,并显示 www.myhost.com/index.html 的内容,但 URL 仅显示 www.myhost.com
我的问题:为什么第一个版本的行为如此?我希望两个版本的行为方式都与第二个版本的行为方式相同。
特别是,我将 RewriteCond %{SCRIPT_FILENAME} !-d
行解释为:如果相对 URL 不是目录,则应用该规则。因此,如果我调用 www.myhost.com,SCRIPT_FILENAME 应该是一个空字符串,这个空字符串既不符合文件也不符合目录的条件,并且应该应用该规则,将 index.html 附加到我的主机 URL 的根目录。 .
我错过了什么?
编辑[2014-12-03] 为了给您一些背景知识,我想在 URL 中隐藏 index.html 但显示其内容。它适用于一个简单的单页网站,包含 css、js、图像,也许还有一些 php。 尽管我有兴趣了解您将如何解决该问题,但本文中的问题不是如何解决它,而是了解 RewriteCond 如何与 -d 参数配合使用。
编辑[2014-12-06] 在下面发布不同的解决方案后,让我尝试解释一下我认为这里发生的事情:
- 我假设 SCRIPT_FILENAME 的空字符串确实被解释为一个目录,即根目录。因此 RewriteRule 从未生效。
- 存在某种到/index.html 的 302 重定向。我现在无法重现它,所以我实际上不确定是什么原因造成的。
最佳答案
mod_rewrite 总是很棘手
首先要考虑的是,还有其他默认值和配置可能会导致第二个问题,即对 /css/
的请求被定向到 /index.html
http://httpd.apache.org/docs/2.0/misc/rewriteguide.html
- 如果
/css/
不存在,或者不允许访问,则可能符合!-d
条件。 - 由于这是 .htaccess,并且这些是继承的,因此很可能匹配第一个条件(空请求)。
- RewriteBase 是为当前目录的相对路径定义的。
- http://httpd.apache.org/docs/current/mod/mod_rewrite.html#RewriteBase
- 这不会是 VirtualHosts 指令中的问题。
- 您可以将 .htaccess 文件添加到
/css/
来覆盖该指令,或者调整您的RewriteRule
以省略 RewriteBase,并且仅在您的代码中使用 RegEx条件。
您的 .htaccess 已调整:
Options -Indexes
RewriteEngine On
RewriteRule ^$ index.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index.html$
RewriteCond %{REQUEST_URI} ^/.+$
RewriteRule ^.+$ index.html [L]
现在,只要 /css/
目录存在,就应该没问题。
关于apache - 为什么 RewriteCond %{SCRIPT_FILENAME} !-d 会破坏我的 RewriteRule,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27260387/