The Host标头告诉网络服务器哪个虚拟主机使用(如果已设置)。您甚至可以使用多个相同的虚拟主机aliases(= 域和通配符域)。在这种情况下,如果您想根据所寻址的不同域提供不同的行为,您仍然可以在 Web 应用程序中手动读取该标头。这是可能的,因为在你的网络服务器中你可以(如果我没记错的话你必须)设置onevhost 成为默认主机。每当以下情况时,都会使用此默认虚拟主机host
标头与任何配置的虚拟主机都不匹配。
这意味着:你说得对,尽管说“多个主机”可能有点误导:主机(寻址的机器)是相同的,真正解析为 IP 地址的内容是不同的域名(包括子域)也称为主机名(但不是主机!)。
虽然不是问题的一部分,但有一个有趣的事实:该规范在早期导致了 SSL 问题,因为 Web 服务器必须提供与客户端已寻址的域相对应的证书。但是,为了知道要使用什么证书,网络服务器应该提前知道寻址的主机名。但由于客户端仅通过加密通道发送该信息(这意味着:在发送证书之后),服务器必须假设您浏览了默认主机。这意味着每个 IP 地址/端口组合都有一个 SSL 安全域。
这已被克服服务器名称指示;然而,这再次破坏了一些隐私,因为服务器名称现在再次以纯文本形式传输,因此每个中间人都会看到哪个主机名您正在尝试连接到。
虽然网络服务器可以从服务器名称指示中知道主机名,但Host
header 并未过时,因为服务器名称指示信息仅在 TLS 握手中使用。对于不安全的连接,根本没有服务器名称指示,因此Host
标头仍然有效(并且必要)。
另一个有趣的事实:大多数 HTTP 服务器实现(如果不是全部)都会拒绝您的 HTTP 请求,如果它不包含恰好一个Host
标头,即使它可以被省略,因为只配置了默认虚拟主机。这意味着 HTTP-(GET-) 请求中所需的最少信息是包含以下内容的第一行:METHOD
RESOURCE
and PROTOCOL VERSION
并且至少Host
标题,像这样:
GET /someresource.html HTTP/1.1
Host: www.example.com
In the 关于“Host”标头的 MDN 文档他们实际上是这样表述的:
所有 HTTP/1.1 请求消息中都必须发送 Host 标头字段。 A
400(错误请求)状态代码将发送到任何 HTTP/1.1 请求
缺少主机标头字段或包含多个主机标头字段的消息。
正如 Darrel Miller 所提到的,完整的规格可以在RFC7230.