在文档根目录中,我放置了一个 .htaccess 文件,内容如下:
ErrorDocument 404 /error.php
由于这是在 .htaccess 文件中,Apache 在相对路径中查找 error.php,因此我可以将不同的 error.php 文件放在不同的子文件夹中,以让它执行不同的 error.php:
request /app1/not-exists.txt : yields /app1/error.php
request /app2/not-exists.txt : yields /app2/error.php
request /not-exists/not-exists.txt : yields /error.php
这是期望的行为。然而,
request /not-exists/app1/not-exists.txt : yields /app1/error.php
request /app2/app1/not-exists.txt : yields /app1/error.php
这似乎不是预期的行为。我预期:
request /not-exists/app1/not-exists.txt : yields /error.php
request /app2/app1/not-exists.txt : yields /app2/error.php (or maybe /error.php)
或者最糟糕的情况是,一些通用的 Apache 错误处理。我是否误解了 Apache 应该在这里做什么?文档似乎没有清楚地说明这一点。
答案1
我认为您在这里的误解是相对路径。
.htaccess
文件没有任何导致路径相对的特殊行为;<Directory>
就配置行为而言,它们本质上与块相同。
ErrorDocument
没有任何上下文的概念;当您输入这样的路径时,/error.php
无论它配置在哪里,总是假定它是相对于文档根目录的。 块或文件mod_rewrite
中的配置使用相对路径,这可能就是您对该行为的想法。<Directory>
.htaccess
有几个关于如何实现这一点的选项...您可以有一个error.php
根据请求路径从每个应用程序错误文件中提取内容的选项吗?
或者您可以只使用mod_rewrite
它来获取所需的错误页面选择行为(虽然获取与您正在寻找的内容相匹配的逻辑有点复杂):
<Directory /path/to/docroot>
# First, we'll have a rule that will handle looking for an error.php in
# the app directory that the request is in...
# Not a file or a directory that exists:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Capture the application directory that we're trying to load from (if
# there is one) for use in the next rule:
RewriteCond %{REQUEST_FILENAME} ^/path/to/docroot/([^/]+)/
# Check if an error.php exists in that directory;
RewriteCond /path/to/docroot/%1/error.php -f
# Send the response to the error page. It should set the 404 response code.
RewriteRule ^([^/]+)/.*$ $1/error.php [L]
# Ok, the previous pile of rules didn't apply; if the user's requesting
# a nonexistent resource, then either the user's not in an app subdirectory,
# or they're in a subdirectory that didn't have an error.php.
# So, this is a lot simpler:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ error.php [L]
</Directory>