apache - 为什么 RewriteCond %{SCRIPT_FILENAME} !-d 会破坏我的 RewriteRule

标签 apache .htaccess mod-rewrite

我的 .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] 在下面发布不同的解决方案后,让我尝试解释一下我认为这里发生的事情:

  1. 我假设 SCRIPT_FILENAME 的空字符串确实被解释为一个目录,即根目录。因此 RewriteRule 从未生效。
  2. 存在某种到/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/

相关文章:

apache - 无法识别一个网站如何重定向到另一个网站

apache - 配置 htaccess 进行 url 重写

regex - .htaccess 301 重定向,保留路径

apache - 如何仅在使用 .htaccess 启用 SSL 的情况下启用目录密码保护?

css - 在子文件夹中使用 htaccess 从 css 动态加载图像

macos - 在 Mac OS X 上为 Xampp Apache 设置 SSL 以解决 Chrome 上的 missing_subjectAltName

c - 是否可以将 zip 文件视为 apache 中的 documentRoot?

php - 跨(子域?)维护 Assets 的最佳实践

linux - 将 http 非 www 转移到 http www,并将 https 非 www 转移到 https www

.htaccess - 您的站点地图不包含任何网址。请验证并重新提交您的站点地图?