上周我花了大量时间试图解决这个问题,但无论我怎么努力,我都无法让它工作。我的网络托管商说他们没有人对 .htaccess 文件有足够的了解,无法让它工作(令人鼓舞,对吧?),我从其购买 CMS 的公司也无法确定解决方案。我也在这里和其他网站上阅读了数十个答案,但我就是无法解决我的问题。
情况是这样的:我的 CMS - Invision Power Board - 生成以下 .htaccess 文件,该文件位于网站的根目录中:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
我有一个子目录sub_dir
,我需要使用子目录中的 .htaccess 文件对其进行密码保护。我通过 cPanel 设置了密码保护,如果网站根目录中的 .htaccess 文件被禁用,它就可以正常工作。但是,如果网站根目录中的 .htaccess 文件未被禁用,那么当我浏览到sub_dir
主页时就会显示。起初我以为显示的主页可能与 404 页面重写有关,但即使我删除了 404 页面的重写条件和规则,主页仍然会显示。
.htaccess文件中的代码sub_dir
为:
AuthUserFile "/home/[user]/public_html/.htpasswd"
AuthType Basic
AuthName "subdir"
require valid-user
正如我之前提到的,当根目录中的 .htaccess 文件被禁用时,密码保护会起作用。当我删除底部的重写条件和规则(index.php 的行)时,它也起作用,但删除 404 页面的重写条件和规则不会影响任何东西。
我尝试了几十种可能的解决方案,但都没有奏效。举几个例子,我尝试了下面 Poncha 的答案:
RewriteCond %{REQUEST_URI} !^sub_dir
我也尝试过这个:
RewriteRule ^/sub_dir - [L]
还有很多很多我现在都不记得的事情。关键是,到目前为止什么都没起作用。我也尝试了所有可能的组合,包括前斜杠和后斜杠。
我的服务器正在运行 Apache 2.2.22。
我真的束手无策了。请帮帮我。
答案1
看起来你已经尝试过了,这是最明显的答案(正如 poncha 指出的那样),并且很可能最有可能出现在 mod_rewrite 教程/指南中。通过使用 排除目录RewriteCond
,注意条件的匹配与 相对应%{REQUEST_URI}
,它以 开头/
“:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/sub_dir
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]
RewriteCond %{REQUEST_URI} !^/sub_dir
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
编辑:
RewriteRule
看看你尝试过的方法,这也是错误的。当它在 htaccess 文件中时,你不希望在匹配中使用前导斜杠:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteRule ^sub_dir - [L]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} .*\.(jpeg|jpg|gif|png)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /public/404.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
答案2
如果请求的路径不是现有文件,也不是现有目录,则此规则转发到主页。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
显然,因为您被转发到主页,所以服务器认为该sub_dir
目录不存在,或者请求sub_dir
被重定向到不存在的内容。
在这种情况下,首先要检查的是,这是否sub_dir
是一个实际的目录,请记住,目录名称将取决于您的区分大小写在大多数运行 Apache 的情况下,同时要记住符号链接不是一定与目录同等对待。
答案3
您不妨尝试在sub_dir
.htaccess 中执行以下操作以禁止 modrewrite 传播到您的sub_dir
:
## turn off rewrite engine
RewriteEngine Off
## now do your auth stuff
AuthUserFile "/home/[user]/public_html/.htpasswd"
AuthType Basic
AuthName "subdir"
require valid-user
如果您确实需要在 sub_dir 中运行重写规则,那么请在 .htaccess 文件中专门执行这些规则,这样就不会产生任何混淆。一旦您执行 RewriteEngine On/Off,父文件夹中的规则就不会直接应用。它们首先从该文件夹读取,然后从根文件夹读取。
答案4
上述解决方案不起作用,因为它们没有解决根本问题,即要从规则中排除的子文件夹受密码保护。
当 Apache 拒绝初始访问并显示登录对话框时,重写规则会启动,但无法将客户端重定向到可访问的文件,因此会出现 404 错误。为了解决这个问题,我们需要提供一个“虚拟”文件,当初始访问尝试失败时,客户端可以重定向到该文件。
ErrorDocument 401 /failed_auth.html
RewriteCond %{REQUEST_URI} ^/pwd-protected-sub-folder/(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^/failed_auth.html$
RewriteRule ^.*$ - [L]