HTTP "Host" 头是什么?

228

鉴于在发送HTTP请求时TCP连接已经建立,因此IP地址和端口是隐含已知的——TCP连接是一个IP + 端口。

那么,我们为什么需要Host头部呢?这只有在将多个主机映射到TCP连接所隐含的IP地址的情况下才需要吗?

2个回答

249
Host头告诉Web服务器使用哪个虚拟主机(如果已设置)。您甚至可以使用多个别名(=域名和通配符域名)来设置相同的虚拟主机。在这种情况下,如果您希望根据不同的域名提供不同的行为,您仍然可以在您的Web应用程序中手动读取该头部。这是可能的,因为在您的Web服务器中,您可以(而且如果我没有记错的话,您必须)设置一个虚拟主机作为默认主机。当host头部与任何配置的虚拟主机都不匹配时,将使用此默认虚拟主机。
这意味着:您理解得对,尽管说“多个主机”可能有些误导:主机(被寻址的机器)是相同的,真正解析为IP地址的是不同的域名(包括子域名),这些域名也被称为主机名(但不是主机!)。
虽然不是问题的一部分,但有一个有趣的事实:这个规范在早期导致了SSL的问题,因为Web服务器必须提供与客户端所访问的域相对应的证书。然而,为了知道要使用哪个证书,Web服务器应该事先知道被访问的主机名。但是,因为客户端只在加密通道上发送这些信息(也就是说:在证书已经发送之后),服务器必须假设您正在浏览默认主机。这意味着每个IP地址/端口组合只能有一个SSL安全的域名。
这个问题已经通过服务器名称指示得到解决;然而,这又破坏了一些隐私,因为服务器名称现在以明文传输,所以任何中间人都可以看到您尝试连接的主机名
虽然Web服务器可以通过服务器名称指示知道主机名,但Host头部并不过时,因为服务器名称指示信息仅在TLS握手中使用。在未加密的连接中,根本没有服务器名称指示,所以Host头部仍然有效(且必要)。
另一个有趣的事实:大多数HTTP服务器实现(如果不是全部)会拒绝你的HTTP请求,如果它不包含恰好一个Host头部,即使它可以被省略,因为只有默认虚拟主机被配置。这意味着在一个HTTP(GET)请求中,最少需要的信息是包含METHODRESOURCEPROTOCOL VERSION的第一行,以及至少一个Host头部,就像这样:
GET /someresource.html HTTP/1.1
Host: www.example.com

MDN关于"Host"头部的文档中,他们实际上是这样表述的:

在所有的HTTP/1.1请求消息中,必须发送一个Host头部字段。对于任何缺少Host头部字段或包含多个Host头部字段的HTTP/1.1请求消息,将发送400(错误请求)状态码。

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

1
大多数网络服务器(如果不是全部)会拒绝您的HTTP请求,如果它不包含恰好一个“Host”头,则会拒绝。这是RFC7230的严格要求:“如果任何HTTP/1.1请求消息缺少Host头字段,或者包含多个Host头字段或具有无效字段值的Host头字段,服务器必须使用400(错误请求)状态码进行响应。” - IInspectable

59

在理解HTTP头部字段的含义和目的时,我总是建议去权威的来源查找。

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

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


那它只是重复了已经在URI中的信息?看起来毫无意义。 - Juan Perez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接