使用动态虚拟主机处理站点未找到和页面未找到

使用动态虚拟主机处理站点未找到和页面未找到

我最近设置了海量虚拟主机在 Apache 中,所以我们需要做的就是创建一个目录来创建一个新的虚拟主机。然后我们还使用通配符 DNS 将所有子域映射到运行我们的 Apache 实例的服务器。

这非常有效,但是现在当 vhost 目录不存在时,我无法将其配置为故障转移到适当的默认/错误页面。

由于我想要处理以下两种错误情况,因此问题似乎被混淆了:

  1. 未找到 vhost,即未找到与 HTTP 主机标头中提供的主机匹配的目录。我希望它显示一个适当的未找到站点错误页面。
  2. vhost 的 404 页面未找到情况。

此外,我在其自己的 vhost 块中有一个专门的“api”vhost。

我尝试了多种变体,但似乎都没有表现出我想要的行为。以下是我现在正在使用的内容:

NameVirtualHost *:80
<VirtualHost *:80>
    DocumentRoot /var/www/site-not-found
    ServerName sitenotfound.mydomain.org

    ErrorDocument 500 /500.html
    ErrorDocument 404 /500.html
</VirtualHost>

<VirtualHost *:80>
    ServerName api.mydomain.org
    DocumentRoot /var/www/vhosts/api.mydomain.org/current
    # other directives, e.g. setting up passenger/rails etc...
</VirtualHost>

<VirtualHost *:80>
    # get the server name from the Host: header
    UseCanonicalName Off
    VirtualDocumentRoot /var/www/vhosts/%0/current
    # other directives ... e.g proxy passing to api etc...
    ErrorDocument 404 /404.html
</VirtualHost>

我的理解是,第一个 vhost 块是默认使用的,因此我将其作为我的捕获所有站点。接下来是我的 API vhost,最后是我的 mass vhost 块。

因此,对于与前两个 ServerName 不匹配且没有相应目录的域,/var/www/vhosts/我预计它会转移到第一个虚拟主机,但是使用此设置,所有域都会解析为我的默认站点未找到。为什么会这样?

通过首先放置 mass-vhost 块,我可以使 mass-vhosts 正确解析,但不能解析我的 site-not-found vhost... 在这种情况下,我似乎无法找到区分 vhost 中的页面级 404 和 VirtualDocumentRoot 无法找到 vhost 目录的情况(这似乎也使用了 404)的方法。

任何能帮助我们摆脱困境的帮助都将不胜感激!

答案1

我原本希望它能转移到第一个虚拟主机,但是使用此设置,所有域都会解析为我的默认站点未找到。这是为什么?

不同的虚拟主机之间没有故障转移逻辑——一旦请求被分配给一个虚拟主机,它就是最终的。

如果您的动态虚拟主机块中没有ServerNameServerAlias,则您依赖“第一个要加载的虚拟主机是默认”行为来将请求分配给该虚拟主机。如果它不是第一个要加载的虚拟主机,则它本质上是惰性的;它无法获取请求。


我对如何处理此问题的建议是让“找不到站点”行为成为代理或重定向到工作站点(然后显示“此处没有内容!”页面),而不是 404 页面的变体。

sitenotfound.mydomain.org虚拟主机向下移动,并将动态虚拟主机放回到顶部,使其成为默认虚拟主机。我们将使用它来提供友好的“此处无网站”页面。

然后,让我们赋予动态虚拟主机在提供内容之前检查站点是否存在的能力。在其虚拟主机中添加:

RewriteEngine On
# If there's no directory where it should be for this host..
RewriteCond /var/www/vhosts/%{HTTP_HOST} !-d
# (or a symlink, we'll be ok with those too)
RewriteCond /var/www/vhosts/%{HTTP_HOST} !-l

# Then, we'll redirect the user to our friendly "no site here" page..
# Note that I'm setting it to 302 so that they won't be cached, since
# you might trigger this accidentally just before a new site goes live..
RewriteRule ^ http://sitenotfound.mydomain.org/invalid-site.html [R=302,L]

# Or if you wanted to proxy instead of redirecting, use this instead:
#RewriteRule ^ http://sitenotfound.mydomain.org/invalid-site.html [P,L]

因此,动态主机现在将在提供内容之前检查站点目录是否存在,并将用户重定向或代理到友好的说明页面。这种行为听起来符合您的需求吗?

相关内容