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

为什么我们需要Host头文件?是否只有在有多个主机映射到TCP连接中隐含的IP地址的情况下才需要这样做?


当前回答

当试图理解HTTP报头的含义和目的时,我总是建议去权威来源。

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

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

其他回答

当试图理解HTTP报头的含义和目的时,我总是建议去权威来源。

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

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

The Host Header tells the webserver which virtual host to use (if set up). You can even have the same virtual host using several aliases (= domains and wildcard-domains). In this case, you still have the possibility to read that header manually in your web app if you want to provide different behavior based on different domains addressed. This is possible because in your webserver you can (and if I'm not mistaken you must) set up one vhost to be the default host. This default vhost is used whenever the host header does not match any of the configured virtual hosts.

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


Although not part of the question, a fun fact: This specification led to problems with SSL in the early days because the web server has to deliver the certificate that corresponds to the domain the client has addressed. However, in order to know what certificate to use, the webserver should have known the addressed hostname in advance. But because the client sends that information only over the encrypted channel (which means: after the certificate has already been sent), the server had to assume you browsed the default host. That meant one SSL-secured domain per IP address / port-combination.

这已经克服了服务器名称指示;然而,这再次破坏了一些隐私,因为服务器名现在再次以纯文本传输,因此每个中间人都会看到您试图连接的主机名。

虽然web服务器从服务器名指示中知道主机名,但主机头并没有过时,因为服务器名指示信息只在TLS握手中使用。对于不安全的连接,根本没有服务器名称指示,所以Host头仍然有效(并且是必要的)。

另一个有趣的事实:大多数web服务器(如果不是全部)拒绝你的HTTP请求,如果它不包含恰好一个Host头,即使它可以被省略,因为只有默认的vhost配置。这意味着http-(get-)请求中最少需要的信息是包含METHOD RESOURCE和PROTOCOL VERSION的第一行,至少还有Host头,就像这样:

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

在MDN文档的“Host”头中,他们实际上是这样表达的:

Host报头字段必须在所有HTTP/1.1请求消息中发送。一个 400(坏请求)状态码将被发送到任何HTTP/1.1请求 消息缺少Host报头字段或包含多个。

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