什么是 HTTP "Host" 标头?



假设在发送HTTP请求时已经建立了TCP连接,则IP地址和端口是隐式已知的 - TCP连接是IP +端口。

那么,为什么我们需要Host标头呢? 这是否仅在有多个主机映射到 TCP 连接中隐含的 IP 地址的情况下才需要?

Host标头告诉 Web 服务器要使用哪个虚拟主机(如果已设置)。您甚至可以使用多个别名(= 域和通配符域)拥有相同的虚拟主机。在这种情况下,如果要根据所寻址的不同域提供不同的行为,您仍然可以在 Web 应用程序中手动读取该标头。这是可能的,因为在您的网络服务器中,您可以(如果我没记错的话,您必须)将一个虚拟主机设置为默认主机。只要host标头与任何已配置的虚拟主机都不匹配,就会使用此默认虚拟主机。

这意味着:你做对了,尽管说"多个主机"可能有些误导:主机(寻址机器)是相同的,真正解析为 IP 地址的是不同的域名(包括子域),也称为主机名(但不是主机!


虽然不是问题的一部分,但一个有趣的事实:这个规范在早期导致了SSL的问题,因为Web服务器必须提供与客户端所寻址的域相对应的证书。但是,为了知道要使用什么证书,Web服务器应该提前知道地址主机名。但是,由于客户端仅通过加密通道发送该信息(这意味着:在发送证书之后),因此服务器必须假定您浏览了默认主机。这意味着每个IP地址/端口组合都有一个SSL安全域。

这已被服务器名称指示克服;但是,这再次破坏了一些隐私,因为服务器名称现在再次以纯文本形式传输,因此每个中间人都会看到您尝试连接到哪个主机名

尽管 Web 服务器会从服务器名称指示中知道主机名,但Host标头并未过时,因为服务器名称指示信息仅在 TLS 握手中使用。对于不安全的连接,根本没有服务器名称指示,因此Host标头仍然有效(并且是必需的)。

另一个有趣的事实:大多数Web服务器(如果不是全部)拒绝您的HTTP请求,如果它不包含一个Host标头,即使它可以被省略,因为只配置了默认的vhost。这意味着HTTP-(GET-)请求中所需的最少信息是包含METHODRESOURCEPROTOCOL VERSION的第一行,至少是Host标头,如下所示:

GET /someresource.html HTTP/1.1
Host: www.example.com

在 MDN 文档中的"主机"标头中,他们实际上是这样表达的:

必须在所有 HTTP/1.1 请求消息中发送主机标头字段。一个 400(错误请求)状态代码将发送到任何HTTP/1.1请求 缺少主机标头字段或包含多个主机标头字段的邮件。

正如Darrel Miller所提到的,完整的规格可以在RFC7230中找到。

在尝试理解HTTP标头的含义和目的时,我总是建议使用权威来源。

请求中的"Host"标头字段提供来自目标 URI 的主机和端口
信息,使源服务器能够
区分资源,同时为单个 IP 地址上的多个
主机名的请求提供服务。

https://www.rfc-editor.org/rfc/rfc7230#section-5.4

最新更新