在 L7 层(应用层)的 HTTP 协议中,域名主要存放在 请求头(Request Headers) 部分。
根据协议版本的不同,具体位置和名称有所差异:
1. HTTP/1.1:Host 请求头
在 HTTP/1.1 协议中,域名被存放在名为 Host 的请求头字段中。
-
位置: 紧跟在起始行(Request Line)之后的首部区域。
-
示例:
HTTP
GET /index.html HTTP/1.1 Host: www.example.com User-Agent: curl/7.68.0 Accept: */* -
强制性: 在 HTTP/1.1 中,
Host字段是唯一强制要求的请求头。如果缺失,服务器会返回400 Bad Request。
2. HTTP/2 & HTTP/3::authority 伪头部
在 HTTP/2 和 HTTP/3 中,为了提高压缩效率和结构化程度,传统的文本请求头被转换为二进制帧,并引入了“伪头部”(Pseudo-Header Fields)。
-
位置: 在标头块(Header Block)中,以冒号
:开头。 -
字段名:
:authority。 -
作用: 它取代了 HTTP/1.1 中的
Host头部,承载域名和端口信息。 -
示例(概念性):
Plaintext
:method: GET :scheme: https :path: /index.html :authority: www.example.com
3. 特殊情况:绝对路径(Absolute URI)
虽然非常少见,但在某些特定的代理请求或早期的 HTTP 标准中,域名可以直接出现在 起始行(Request Line) 中。
- 形式:
GET http://www.example.com/index.html HTTP/1.1 - 逻辑: 当请求行中包含完整的绝对 URI 时,服务器通常会忽略
Host头部的值,而以请求行中的域名为准。
4. 第一性原理:为什么 L7 需要显式包含域名?
从底层逻辑(第一性原理)出发,域名在 L7 存在的必要性源于 “虚拟主机(Virtual Hosting)” 技术:
- IP 地址的不足: 在 L3(网络层),数据包只知道目标 IP。但在云计算和 Web 服务器中,一个公网 IP 通常会挂载成百上千个不同的网站(域名)。
- 分发逻辑: 当 TCP 连接建立后,服务器收到 L7 的 HTTP 请求。如果报文中不携带域名,服务器将无法判断该将请求转发给哪一个虚拟主机或后端服务。
- 解耦: L7 的域名信息允许应用层逻辑与底层的 IP 网络寻址实现逻辑解耦。
补充:L7 之前的域名线索 (SNI)
虽然你问的是 L7,但在建立 HTTPS 连接的加密握手阶段(TLS 层),域名也会出现在 SNI (Server Name Indication) 扩展中。这是为了让服务器在解密 HTTP 内容之前,就知道该出示哪张 SSL 证书。