Apache2:400 带有重写规则的错误请求,错误日志中没有任何内容?

Apache2:400 带有重写规则的错误请求,错误日志中没有任何内容?

这让我抓狂了。

背景:我正在使用 Mac OS X 10.6 自带的内置 Apache2 和 PHP

我有一个如下的虚拟主机设置:

NameVirtualHost *:81

<Directory "/Users/neezer/Sites/">
    Options Indexes MultiViews
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

<VirtualHost *:81>
    ServerName lobster.dev
    ServerAlias *.lobster.dev
    DocumentRoot /Users/neezer/Sites/lobster/www

    RewriteEngine On
    RewriteCond $1 !^(index\.php|resources|robots\.txt)
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php/$1 [L,QSA]

    LogLevel debug
    ErrorLog /private/var/log/apache2/lobster_error
</VirtualHost>

这是在/private/etc/apache2/users/neezer.conf

我的代码lobster project是 PHP,其中CodeIgniter 框架. 正在尝试加载http://lobster.dev:81/给我:

400 错误请求

通常情况下,我会去检查我的日志以查看是什么原因造成的,但我的日志是空的!我查看了和/private/var/log/apache2/error_log/private/var/log/apache2/lobster_error都没有记录任何与 400 相关的消息。我已在中LogLevel设置为。debug/private/etc/apache2/http.conf

删除重写规则可以消除错误,但这些相同的规则在我的 MAMP 主机上有效。我已仔细检查并rewrite_module已加载到我的默认 Apache 安装中。我的http.conf可以在这里找到:https://gist.github.com/1057091

怎么回事?如果您需要任何其他信息,请告诉我。

注意:我不想.htaccess在项目目录中添加重写规则(它已被签入到 git repo 中并且我不想触碰它)。

答案1

对于复杂的 mod_rewrite 规则,最好记录事件序列以查看发生了什么。使用重写日志,并调高重写日志级别查看详细信息。

mod_rewrite 非常灵活,可以使用重写规则做很多事情,但也相当复杂。局外人如果不了解更广泛的背景,调试规则会很困难。最好的办法是自己调试。在一个窗口中查看日志,同时在另一个窗口中尝试配置更改。进行小幅更改,保存文件,重新加载 apache 并再次点击 URL。重复。

以下是 Apache 对 RewriteLog 的一个很好的描述手动的

重写日志

在使用 mod_rewrite 强大而复杂的功能时,几乎总是需要使用 RewriteLog 来帮助调试。此日志文件会详细分析重写引擎如何转换请求。详细程度由 RewriteLogLevel 指令控制。

答案2

您在上下文中的替换<virtualhost>使用了非绝对 URL。您无法在 Directory/htaccess 上下文之外执行此操作。

答案3

还有一些其他的注释,由于篇幅过长,无法包含在简单的评论中:

RewriteCond $1有效,但它非常危险且脆弱。特别是,您可以轻松重写 RewriteRule 以完全禁用该 RewriteCond 的功能,而您永远不会知道您已经这样做了。%{REQUEST_URI}建议使用 作为解决方案,就像 一样RewriteCond %{REQUEST_URI} ^/(index\.php|resources|robots\.txt)

下一期:这两行:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

无法像所展示的那样发挥作用。它们要么需要放在<Directory>节内,要么需要修改以使用前瞻宏(例如RewriteCond %{LA-U:REQUEST_FILENAME} !-f)。

您需要删除 的实际原因/是,它会从 RewriteRule 的第一个参数中.htaccess删除开头,而它会完整地传递给 httpd.conf(或其d 文件)中的 RewriteRules,如果您尝试将此规则移回 .htaccess,这一点很重要。您可以通过执行类似 的操作将规则重新设计为 .htaccess/httpd.conf 不可知的。//IncludeRewriteRule ^/?(.*)$ index.php/$1 [L,QSA]

最后一点:正如您在上面的规则中所看到的,您不需要使用/反斜杠进行转义。

相关内容