【发布时间】:2020-10-02 05:34:51
【问题描述】:
我的网络服务器目前有一个有趣的问题,我找不到解决方案,希望能得到您的帮助。
我已经在 Arch Linux 上设置了一个 Apache 服务器,并且我正在使用 VirtualDocumentRoot 来创建“开发域”。配置文件如下所示:
ServerName localhost
<VirtualHost *:80>
UseCanonicalName Off
DocumentRoot /srv/http/
ServerName localhost
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /srv/http/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/httpd/error_log
LogLevel warn rewrite:trace3
CustomLog /var/log/httpd/access_log combined
</VirtualHost>
<VirtualHost *:80>
UseCanonicalName Off
VirtualDocumentRoot /srv/http/%-2/webroot/
VirtualScriptAlias /srv/http/%-2/cgi-bin/
DocumentRoot /srv/http/
ServerAlias *.localhost
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /srv/http/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/httpd/error_log
LogLevel warn rewrite:trace3
LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
CustomLog /var/log/httpd/access_log vcommon
</VirtualHost>
我在服务器上的文件结构就是这样构建的:
root folder (/srv/http/)
|- project folder (e.g. projectname)
|- some project stuff (e.g. nbproject)
|- some project stuff (e.g. vendor)
|- public folder (webroot)
因此,如果我访问 http://localhost,它将显示所有项目。点击一个项目我可以看到所有文件夹,点击“webroot”我会看到项目的最终主页。
由于 VirtualDocumentRoot 配置,我还可以直接访问 http://projectname.localhost,它将提供 /srv/http/projectname/webroot 的内容,从而可以像在“真实条件”中一样测试网页。
对于其中一个项目,我创建了一个 MVC 系统,该系统的构建类似于例如WordPress。如果你调用类似http://projectname.localhost/foo/bar 的东西,服务器应该提供文件 /srv/http/projectname/webroot/index.php 并将 foo 和 bar 作为参数传递给索引文件。 这是通过将 .htaccess 文件放入包含以下内容的 webroot 文件夹来完成的:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
这两个版本都很好用。所以 http://localhost/projectname/webroot/foo/bar 和 http://projectname.localhost/foo/bar 提供完全相同的结果。
现在有趣的事情来了:
如果在这个 MVC 页面上用户想要访问一个不存在的主题,他将被重定向到页面 http://projectname.localhost/error/404。 但是这个页面不能调用!我没有显示花哨的错误页面,而是得到了服务器内部错误页面。文件夹“错误”实际上并不存在。这没关系,因为 .htaccess 仍应为 index.php 提供服务。但是.htaccess 没有被执行。
所以我做了一些测试,得到了这个结果(括号中你可以看到重定向是否有效以及服务器回复状态码):
- http://projectname.localhost/error [OK 200]
- http://projectname.localhost/error/404 [404 挪威克朗]
- http://projectname.localhost/error/?test [403 挪威克朗]
- http://projectname.localhost/error?test[OK 200]
- http://projectname.localhost/something [OK 200]
- http://projectname.localhost/something/404 [OK 200]
- http://projectname.localhost/something/?test [OK 200]
- http://projectname.localhost/something?test[OK 200]
- http://localhost/projectname/webroot/error [OK 200]
- http://localhost/projectname/webroot/error/404 [OK 200]
- http://localhost/projectname/webroot/error/?test [OK 200]
- http://localhost/projectname/webroot/error?test [OK 200]
- http://localhost/projectname/webroot/something [OK 200]
- http://localhost/projectname/webroot/something/404 [OK 200]
- http://localhost/projectname/webroot/something/?test [OK 200]
- http://localhost/projectname/webroot/something?test [OK 200]
仅当我使用 VirtualDocumentRoot 版本并且 URL 子路径以“错误”开头并且路径以某种方式继续时才会出现问题。
我检查了日志文件,一切正常,access.log 如下所示:
projectname.localhost 127.0.0.1 - - [02/Oct/2020:06:00:00 +0000] "GET /something/404 HTTP/1.1" 200 -
error.log 看起来像这样:
[Fri Oct 02 06:00:00.919667 2020] [rewrite:trace3] [pid 80730] mod_rewrite.c(483): [client 127.0.0.1:33272] 127.0.0.1 - - [projectname.localhost/sid#5579881cec50][rid#5579883c5440/initial] [perdir /srv/http/projectname/webroot/] add path info postfix: /srv/http/projectname/webroot/something -> /srv/http/projectname/webroot/something/404
[Fri Oct 02 06:00:00.919721 2020] [rewrite:trace3] [pid 80730] mod_rewrite.c(483): [client 127.0.0.1:33272] 127.0.0.1 - - [projectname.localhost/sid#5579881cec50][rid#5579883c5440/initial] [perdir /srv/http/projectname/webroot/] strip per-dir prefix: /srv/http/projectname/webroot/something/404 -> something/404
[Fri Oct 02 06:00:00.919736 2020] [rewrite:trace3] [pid 80730] mod_rewrite.c(483): [client 127.0.0.1:33272] 127.0.0.1 - - [projectname.localhost/sid#5579881cec50][rid#5579883c5440/initial] [perdir /srv/http/projectname/webroot/] applying pattern '^' to uri 'something/404'
[Fri Oct 02 06:00:00.919761 2020] [rewrite:trace2] [pid 80730] mod_rewrite.c(483): [client 127.0.0.1:33272] 127.0.0.1 - - [projectname.localhost/sid#5579881cec50][rid#5579883c5440/initial] [perdir /srv/http/projectname/webroot/] rewrite 'something/404' -> 'index.php'
[Fri Oct 02 06:00:00.919773 2020] [rewrite:trace3] [pid 80730] mod_rewrite.c(483): [client 127.0.0.1:33272] 127.0.0.1 - - [projectname.localhost/sid#5579881cec50][rid#5579883c5440/initial] [perdir /srv/http/projectname/webroot/] add per-dir prefix: index.php -> /srv/http/projectname/webroot/index.php
[Fri Oct 02 06:00:00.919784 2020] [rewrite:trace2] [pid 80730] mod_rewrite.c(483): [client 127.0.0.1:33272] 127.0.0.1 - - [projectname.localhost/sid#5579881cec50][rid#5579883c5440/initial] [perdir /srv/http/projectname/webroot/] strip document_root prefix: /srv/http/projectname/webroot/index.php -> /index.php
[Fri Oct 02 06:00:00.919793 2020] [rewrite:trace1] [pid 80730] mod_rewrite.c(483): [client 127.0.0.1:33272] 127.0.0.1 - - [projectname.localhost/sid#5579881cec50][rid#5579883c5440/initial] [perdir /srv/http/projectname/webroot/] internal redirect with /index.php [INTERNAL REDIRECT]
[Fri Oct 02 06:00:00.919839 2020] [rewrite:trace3] [pid 80730] mod_rewrite.c(483): [client 127.0.0.1:33272] 127.0.0.1 - - [projectname.localhost/sid#5579881cec50][rid#5579883b8010/initial/redir#1] [perdir /srv/http/projectname/webroot/] strip per-dir prefix: /srv/http/projectname/webroot/index.php -> index.php
[Fri Oct 02 06:00:00.919851 2020] [rewrite:trace3] [pid 80730] mod_rewrite.c(483): [client 127.0.0.1:33272] 127.0.0.1 - - [projectname.localhost/sid#5579881cec50][rid#5579883b8010/initial/redir#1] [perdir /srv/http/projectname/webroot/] applying pattern '^' to uri 'index.php'
[Fri Oct 02 06:00:00.919868 2020] [rewrite:trace1] [pid 80730] mod_rewrite.c(483): [client 127.0.0.1:33272] 127.0.0.1 - - [projectname.localhost/sid#5579881cec50][rid#5579883b8010/initial/redir#1] [perdir /srv/http/projectname/webroot/] pass through /srv/http/projectname/webroot/index.php
对于 NOK,access.log 看起来像这样:
projectname.localhost 127.0.0.1 - - [02/Oct/2020:06:00:00 +0000] "GET /error/404 HTTP/1.1" 404 1131
并且error.log 不包含任何内容。
所以也许您知道为什么只有在 URL 路径中使用“错误”并使用 VirtualDocumentRoot 时才会触发此 .htaccess?
谢谢!
【问题讨论】:
-
我很少遇到如此详细和定义明确的问题++
-
您在项目路径或别名路径中的任何位置是否有任何名为
/error的文件或目录?