【问题标题】:What is HTTP "Host" header?什么是 HTTP“主机”标头?
【发布时间】:2025-12-27 04:00:10
【问题描述】:

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

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

【问题讨论】:

    标签: http http-headers


    【解决方案1】:

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

    这意味着:你说得对,虽然说“多台主机”可能会有些误导:主机(寻址机器)是相同的,真正解析到 IP 地址的是不同的域名 em>(包括子域)也称为主机名(但不是主机!)。


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

    Server Name Indication 解决了这个问题;但是,这再次破坏了一些隐私,因为服务器名称现在再次以纯文本形式传输,因此每个中间人都会看到您尝试连接的哪个主机名

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

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

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

    MDN Documentation on the "Host" header 中,他们实际上是这样表述的:

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

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

    【讨论】:

      【解决方案2】:

      在尝试了解 HTTP 标头的含义和用途时,我始终建议您访问权威来源。

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

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

      【讨论】: