为什么这个.htaccess文件不显示存在的文件


Why is this .htaccess file not presenting files that exist?

我有一个非常简单的.htaccess文件,旨在将任何请求重定向到index.php,如果该文件不存在并且不是目录。

[ 在建议修改之前 ]

<IfModule mod_rewrite.c>
RewriteEngine On
#REWRITE RULES
#---------------------
#RULE COMPLETEREWRITE
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.* index.php
</IfModule>

[ 修改建议后 ]

<IfModule mod_rewrite.c>
RewriteEngine On
#REWRITE RULES
#---------------------
#RULE COMPLETEREWRITE
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [L]
</IfModule>

( htaccess 修改之间没有变化 )

目前,无论文件是否存在.php它都会重定向到索引。谁能解释为什么会这样?

这似乎是一个愚蠢的问题 - 但我做了一些研究,结果很少。

这在 Ubuntu 下的 Apache 2.4 中运行,启用了mod_rewrite,显然我希望。

情况:

位于"/resource/img/panoramas/1.png"的文件存在。通过本地文件浏览器、SSH 和 FTP 在我的 VM 文件系统上进行了验证。

在实现 htaccess 文件之前,可以远程访问此文件。我有一个缓存版本来证明这一点。

实现 htaccess 文件后,任何命中此路径的尝试都会返回 index.php。

====

===========

我的 CMS 的核心包含使用重写时创建标头的方法。如果我登陆索引本身.php,我不会标记重写(如预期的那样)。如果我在此目录下遇到任何其他路径,我最终会在 index.php 带有重写标志(部分预期)。如果文件存在,但仍与预期相反,则不应如此。

还需要注意的是,此htaccess文件是从web.config(IIS)文件自动生成的,并且在IIS下,这些规则和我的CMS都完全按预期工作。

最后(与最佳实践相反),整个目录被chmod到777,以消除文件无法访问的可能性。

试试这个:

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f 
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^.* index.php

这是一个疯狂的猜测。如果我们要提供的不仅仅是猜测,您应该启用日志记录并发布日志,因为可能出错的事情的表面很大;)

RewriteLog /var/log/apache2/rewrite.log                                                                                                                                                                      
RewriteLogLevel 5

您可以尝试对文件/目录进行以下替代检查:

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-l
RewriteRule ^ index.php [L]

在正常情况下,%{DOCUMENT_ROOT}%{REQUEST_URI}解析为与%{REQUEST_FILENAME}相同的完整文件系统路径,但在您的情况下%{REQUEST_FILENAME}无法解析。

如果

文件/页面不存在,您可以使用404 Error方式将用户重定向到index

如下:

ErrorDocument 404 /index.php

这是非常不寻常的,显然不是预期的结果。因此,可以安全地假设问题可能是另一个.htaccess文件干扰了您的重写。或者,您可以在另一个 Apache 配置文件中有一个正在执行此操作的指令。

为了追踪手头问题的根本原因,你需要告诉Apache记录/跟踪重写。当您运行 Apache 2.4 时,您需要为虚拟主机设置LogLevel,如下所示:

LogLevel warn mod_rewrite.c:trace4 # where trace<n> is the level of tracing

(旁注:以前版本的 Apache 使用了 RewriteLog,但现在在最新的 Apache 2.4 中已弃用。

然后,您可以进入站点的日志,在某处您应该看到以下内容:

[Tue Jun 16 16:51:40.123993 2015] [rewrite:trace4] [pid 5412:tid 1680] mod_rewrite.c(475): [client <client_ip_port>] <ip> - - [<your_domain>/sid#1406168][rid#1cb2150/initial] [perdir <document_root>] RewriteCond: input='<document_root>' pattern='!-f' => matched
[Tue Jun 16 16:51:40.123993 2015] [rewrite:trace4] [pid 5412:tid 1680] mod_rewrite.c(475): [client <client_ip_port>] <ip> - - [<your_domain>/sid#1406168][rid#1cb2150/initial] [perdir <document_root>] RewriteCond: input='<document_root>' pattern='!-d' => not-matched

如果您没有看到这些行(特别是第一行),则可能意味着该文件确实不存在。如果该线存在,那么恐怕是其他原因导致了问题。尽管如此,使用跟踪器将帮助您识别问题,以便您可以轻松解决它。

可能是因为你捕获了所有内容并将其发送到索引.php在RewriteRule中尝试:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]