意外的 .htaccess 相关 ErrorDocument 行为

意外的 .htaccess 相关 ErrorDocument 行为

在文档根目录中,我放置了一个 .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>

相关内容