这让我抓狂了。
背景:我正在使用 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 不可知的。/
/
Include
RewriteRule ^/?(.*)$ index.php/$1 [L,QSA]
最后一点:正如您在上面的规则中所看到的,您不需要使用/
反斜杠进行转义。