在我的Apache设置中,我有一个包含错误页面的目录(404 403)。但是,我不希望这个目录直接可见 - 我想访问它以返回404.所以我做的是:
# Use /hidden/404/ as the 404 page
ErrorDocument 404 /hidden/404/
# Use /hidden/403/ as the 403 page
ErrorDocument 403 /hidden/403/
<Directory /path/to/root/hidden/>
# All requests return 404
RedirectMatch 404 .*
</Directory>
问题是,在这种情况下,Apache似乎不愿意在 all 中提供文件,即使我明确告诉它(即处理404和403错误)。事实上,当我访问/hidden
时,我收到以下消息:
The requested URL /hidden/404/ was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an
ErrorDocument to handle the request.
我可以告诉Apache禁止访问该目录,同时仍然允许自己在必要时提供这些文件吗?
答案 0 :(得分:0)
好的,我想出了办法。
我所做的是使用mod_rewrite
,它是一个Apache模块(默认情况下附带所有安装),用于动态重写请求的URL。这是代码:
# Custom error pages
ErrorDocument 404 /hidden/404/index.html
ErrorDocument 403 /hidden/403/index.html
# Pretend that /hidden doesn't exist
# (unless this is an internal redirect,
# such as rendering a 404 or 403)
RewriteCond %{ENV:REDIRECT_STATUS} =""
RewriteRule ^/hidden/.* - [L,R=404]
让我们来看看这些内容。 ErrorDocument
指令没有改变 - 它们只是说出发生给定错误时应该提供哪个页面。
真正的肉类在RewriteCond
和RewriteRule
指令中。 RewriteRule
指令所说的是:如果请求的url的路径与正则表达式^/hidden/.*
匹配(实质上是与/ hidden /或其子树中的任何内容相对应的路径),请保持url不变(那是-
意味着什么),但不要再解释RewriteRule
指令(L
意味着什么),并返回404错误代码(R=404
的意思)。
这与ErrorDocument 404 /hidden/404/index.html
指令相结合似乎可以解决问题。但问题是,当Apache开始提供/hidden/404/index.html
时,它会再次运行这些规则。这意味着执行了RewriteRule
指令,而后者又表示要渲染404,而整个事情只是无限循环。
因此,我们使用RewriteCond
指令来确保这不会发生。 RewriteCond
指令是条件 - 下面的RewriteRule
指令只有在条件满足时才会执行。在这种情况下的条件是&#34;环境变量REDIRECT_STATUS
等于空字符串。&#34;现在,REDIRECT_STATUS
是由ErrorDocument
设置的环境变量,并保存正在重定向的状态代码(因此,如果ErrorDocument 404 ...
指令已被触发,则将其设置为价值&#34; 404&#34;)。但是,如果没有执行ErrorDocument
指令,则不会设置REDIRECT_STATUS
,因此询问其值只会返回空字符串。因此,RewriteCond %{ENV:REDIRECT_STATUS} =""
基本上表示,&#34;不要在下面评估RewriteRule
指令,除非我们不在提供错误页面。&#34; < / p>
注意:如果查看了RewriteRule
文档,您可能已经注意到R
参数应该执行显式重定向。它在这种情况下正常工作的原因是R
参数的未记录特征是它只重定向300类代码。因此,R=404
不会执行显式重定向,只会执行内部重定向。