对于我的网站,我有以下 apache 配置:
<VirtualHost _default_:80>
#.........
DocumentRoot /var/www/web
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/web/>
Options FollowSymLinks MultiViews Includes
AllowOverride All
Order allow,deny
allow from all
</Directory>
#.........
<Directory "/var/www/web/">
RewriteEngine On
# uncomment the following line, if you are having trouble
# getting no_script_name to work
RewriteBase /
# redirect www if necessary
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
# we skip all files with .something
RewriteCond %{REQUEST_URI} \..+$
# RewriteCond %{REQUEST_URI} !\.html$
RewriteRule .* - [L]
#root url
RewriteRule ^$ index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# no, so we redirect to our front web controller
RewriteRule ^(.*)$ index.php [QSA,L]
</Directory>
</VirtualHost>
基本上,对没有点的不存在文件的任何请求都会重定向到我的前端 Web 控制器。它似乎运行良好,但我不明白为什么日志文件中有许多以下行:
[Mon Aug 06 12:29:52 2012] [error] [client 188.165.238.151] File does not exist: /var/www/web/webcalendar
[Mon Aug 06 12:29:52 2012] [error] [client 188.165.238.151] File does not exist: /var/www/web/calendar
[Mon Aug 06 12:29:52 2012] [error] [client 188.165.238.151] File does not exist: /var/www/web/webcal
[Mon Aug 06 12:29:52 2012] [error] [client 188.165.238.151] File does not exist: /var/www/web/cal
[Mon Aug 06 12:29:52 2012] [error] [client 188.165.238.151] File does not exist: /var/www/web/install
http://domain.com/cal
如果我尝试类似或的URL http://www.domain.com/cal
,我的日志会显示由我的应用程序而不是 Apache 返回的错误:
[Wed Aug 08 09:06:04 2012] [error] [client 82.60.63.56] Action "cal/index" does not exist.
apache 怎么可能直接返回错误而不将请求发送给我的应用程序?
编辑:
这是输出apache2ctl -S
:
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
_default_:443 mydomain.com (/etc/apache2/sites-enabled/mydomain-ssl:2)
*:80 is a NameVirtualHost
default server mydomain.com (/etc/apache2/sites-enabled/mydomain:1)
port 80 namevhost mydomain.com (/etc/apache2/sites-enabled/mydomain:1)
Syntax OK
更新:
以下是请求的日志:
211.154.213.122 - - [15/Aug/2012:12:39:45 +0000] [mydomain.com/sid#7f87db86bf40][rid#7f87db6990a0/initial] (3) [perdir /var/www/web/] add path info postfix: /var/www/web/phpMyAdmin -> /var/www/web/phpMyAdmin/scripts/setup.php
211.154.213.122 - - [15/Aug/2012:12:39:45 +0000] [mydomain.com/sid#7f87db86bf40][rid#7f87db6990a0/initial] (3) [perdir /var/www/web/] strip per-dir prefix: /var/www/web/phpMyAdmin/scripts/setup.php -> phpMyAdmin/scripts/setup.php
211.154.213.122 - - [15/Aug/2012:12:39:45 +0000] [mydomain.com/sid#7f87db86bf40][rid#7f87db6990a0/initial] (3) [perdir /var/www/web/] applying pattern '^(.*)$' to uri 'phpMyAdmin/scripts/setup.php'
211.154.213.122 - - [15/Aug/2012:12:39:45 +0000] [mydomain.com/sid#7f87db86bf40][rid#7f87db6990a0/initial] (3) [perdir /var/www/web/] add path info postfix: /var/www/web/phpMyAdmin -> /var/www/web/phpMyAdmin/scripts/setup.php
211.154.213.122 - - [15/Aug/2012:12:39:45 +0000] [mydomain.com/sid#7f87db86bf40][rid#7f87db6990a0/initial] (3) [perdir /var/www/web/] strip per-dir prefix: /var/www/web/phpMyAdmin/scripts/setup.php -> phpMyAdmin/scripts/setup.php
211.154.213.122 - - [15/Aug/2012:12:39:45 +0000] [mydomain.com/sid#7f87db86bf40][rid#7f87db6990a0/initial] (3) [perdir /var/www/web/] applying pattern '.*' to uri 'phpMyAdmin/scripts/setup.php'
211.154.213.122 - - [15/Aug/2012:12:39:45 +0000] [mydomain.com/sid#7f87db86bf40][rid#7f87db6990a0/initial] (1) [perdir /var/www/web/] pass through /var/www/web/phpMyAdmin
这会产生以下错误:
[Wed Aug 15 12:39:45 2012] [error] [client 211.154.213.122] File does not exist: /var/www/stmtc/web/phpMyAdmin
答案1
如果不查看您的整个配置,很难确定,但从表面上看,这看起来像是“尾部斜杠问题”的变体。我怀疑,通过一些分析和实验,您可能会验证这一点。
如果它是有用的,Apache 的情况是,没有尾部斜杠或文件扩展名的请求是不明确的 - Apache 不知道请求是针对文件资源还是针对目录资源。它看到请求,解析它,并在文件系统上查找资源,假设它是一个文件。如果文件不存在,它会通过添加尾部斜杠发出重定向,假设它应该再次尝试请求,但由于文件不存在,因此作为目录级请求。
我意识到这并不完全符合您的问题描述,但您的重写可能会在这里进行干预,并使这个过程比平时不那么直观。
@larsks 关于打开详细重写日志的建议非常好,应该可以解释一下正在发生的事情。
答案2
感谢@larsks 的建议并阅读重写日志,我了解到记录的错误:
File does not exist: /var/www/web/phpMyAdmin
不是针对确切的请求http://domain.com/phpMyAdmin
,而是针对请求http://domain.com/phpMyAdmin/scripts/setup.php
。由于文件名中的点,未调用重写规则。因此一切正常且正常工作。