我的文件层次结构如下:
/public_html/directory/
/public_html/directory/index.php
/public_html/directory/file.php
我想将请求转发到最合适的链接。例如,
mydomain.com/directory/
至mydomain.com/directory/index.php
mydomain.com/directory/file
至mydomain.com/directory/file.php
如果发生404或500错误,请将其转发至/public_html/error.php
为此,我在.htaccess
Options +SymLinksIfOwnerMatch -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# don't touch /forum URIs
RewriteRule ^forums/ - [L,NC]
# hide .php extension snippet
#To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+).php [NC]
RewriteRule ^ %1 [R,L]
# To internally forward /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
ErrorDocument 404 /error.php
ErrorDocument 500 /error.php
如果我提出上述要求,它可以正常工作。但是,如果我请求页面mydomain.com/directory/file/scrap
,那么它会生成Internal Server Error
我认为是因为file
不是目录。但我不知道如何在这里解决这个问题。请建议。
服务器的错误输出中还提到了另外一行,最后是关于500的ErrorDocument。完整输出如下:
内部服务器错误
服务器遇到内部错误或配置错误 无法完成您的请求。
请联系服务器管理员root @ localhost并告知 他们发生错误的时间,以及你可能做过的任何事情 可能导致错误。
有关此错误的详细信息可能在服务器错误中可用 日志中。
此外,遇到500内部服务器错误错误 尝试使用ErrorDocument来处理请求。
答案 0 :(得分:2)
这种情况正在发生,因为%{REQUEST_FILENAME} -f
条件还会检查“路径信息”样式请求。所以当你要求时:
mydomain.com/directory/file/scrap
重写引擎会看到文件/directory/file.php
,并假设您正在制作路径信息样式请求,例如/directory/file.php/scrap
这会导致重写引擎循环。
您需要将该条件更改为:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
哦,至于ErrorDocument
的事情,我很确定正在发生的事情是重写模块完全结束了管道中的URL处理。这意味着,如果mod_rewrite翻转并结束所有处理,则将永远不会应用在管道的 end 处应用的指令。这就是为什么你的ErrorDocument
指令没有被应用的原因。如果您修复了重写问题,您会注意到500错误文档将再次起作用。
答案 1 :(得分:0)
根据上面的配置,我会说/error.php
存在问题。
假设没有scrap.php
,mydomain.com/directory/file/scrap
将不会被重写。
500错误还提到在尝试使用ErrorDocument时遇到错误。
尝试使用静态error.html
代替动态error.php
来缩小问题范围。
您还可以记录重写以验证它们是否正常工作:
RewriteLogLevel 9
RewriteLog /var/log/httpd/rewrite_log