HTTP 消息
HTTP 消息是服务器和客户端之间交换数据的途径。消息分为两种:请求,由客户端发送,用于触发服务器上的操作;以及响应,即来自服务器的答案。
Web 开发人员,或网站管理员,很少自己编写这些文本形式的 HTTP 消息:软件、Web 浏览器、代理或 Web 服务器会执行此操作。它们通过配置文件(针对代理或服务器)、API(针对浏览器)或其他接口提供 HTTP 消息。
HTTP 请求和响应具有相似的结构,由以下部分组成:
- 起始行,描述要执行的请求,或描述其成功或失败的状态。这始终是单行。
- 一组可选的HTTP 标头,用于指定请求,或描述消息中包含的正文。
- 一个空行,表示请求的所有元信息已发送。
- 一个可选的正文,包含与请求相关联的数据(如 HTML 表单的内容),或与响应相关联的文档。正文的存在及其大小由起始行和 HTTP 标头指定。
HTTP 消息的起始行和 HTTP 标头统称为请求的头部,之后包含其内容的部分称为正文。
HTTP 请求
请求行
注意:在请求中,起始行称为“请求行”。
HTTP 请求是由客户端发送的消息,用于在服务器上发起操作。它们的请求行包含三个元素:
- HTTP 方法,动词(如
GET
、PUT
或POST
)或名词(如HEAD
或OPTIONS
),描述要执行的操作。例如,GET
表示应获取资源,而POST
表示将数据推送到服务器(创建或修改资源,或生成要发回的临时文档)。 - 请求目标,通常是 URL,或协议、端口和域的绝对路径,通常由请求上下文确定。此请求目标的格式因不同的 HTTP 方法而异。它可以是:
- 绝对路径,最后以
'?'
和查询字符串结尾。这是最常见的形式,称为原点形式,并用于GET
、POST
、HEAD
和OPTIONS
方法。POST / HTTP/1.1
GET /background.png HTTP/1.0
HEAD /test.html?query=alibaba HTTP/1.1
OPTIONS /anypage.html HTTP/1.0
- 完整 URL,称为绝对形式,主要用于连接到代理时使用
GET
。GET https://mdn.org.cn/en-US/docs/Web/HTTP/Messages HTTP/1.1
- URL 的授权组件,包括域名和可选的端口(以
':'
为前缀),称为授权形式。它仅在设置 HTTP 隧道时与CONNECT
一起使用。CONNECT developer.mozilla.org:80 HTTP/1.1
- 星号形式,一个简单的星号 (
'*'
),用于OPTIONS
,表示整个服务器。OPTIONS * HTTP/1.1
- 绝对路径,最后以
- HTTP 版本,它定义了剩余消息的结构,充当响应中预期使用的版本的指示器。
标头
HTTP 标头 来自请求,遵循与 HTTP 标头相同的基本结构:一个不区分大小写的字符串,后跟一个冒号 (':'
) 和一个结构取决于标头类型的值。整个标头,包括其值,都是一行,可以很长。
请求中可以出现许多不同的标头。它们可以分为几个组:
- 通用标头,如
Via
,适用于整个消息。 - 请求标头,如
User-Agent
或Accept
,通过进一步指定(如Accept-Language
)、提供上下文(如Referer
)或有条件地限制(如If-None-Match
)来修改请求。 - 表示标头,如
Content-Type
,用于描述消息数据的原始格式以及应用的任何编码(仅在消息包含正文时存在)。
正文
响应的最后一部分是正文。并非所有响应都包含正文:如果响应的状态码足以回答请求,而无需包含消息 内容(如 201 Created
或 204 No Content
),则通常不包含正文。
正文可以大体上分为两类:
- 单资源正文,由单个文件组成,由两个标头定义:
Content-Type
和Content-Length
。 - 多资源正文,由多部分正文组成,每个部分包含不同的信息。这通常与 HTML 表单 相关联。
HTTP 响应
状态行
标头
HTTP 标头 对于响应,遵循与任何其他标头相同的结构:一个不区分大小写的字符串,后跟一个冒号 (':'
) 和一个结构取决于标头类型的值。整个标头,包括其值,都显示为一行。
响应中可以出现许多不同的标头。它们可以分为几个组:
- 通用标头,如
Via
,适用于整个消息。 - 响应标头,如
Vary
和Accept-Ranges
,提供有关服务器的附加信息,这些信息不适合放在状态行中。 - 表示标头,如
Content-Type
,用于描述消息数据的原始格式以及应用的任何编码(仅在消息包含正文时存在)。
正文
响应的最后一部分是正文。并非所有响应都包含正文:如果响应的状态码足以回答请求,而无需包含内容(如 201 Created
或 204 No Content
),则通常不包含正文。
正文可以大体上分为三类:
- 单资源正文,由一个已知长度的单个文件组成,由两个标头定义:
Content-Type
和Content-Length
。 - 单资源正文,由一个未知长度的单个文件组成,通过块编码,
Transfer-Encoding
设置为chunked
。 - 多资源正文,由多部分正文组成,每个部分包含不同的信息部分。这些相对罕见。
HTTP/2 帧
HTTP/1.x 消息在性能方面存在一些弊端:
- 标头与正文不同,未压缩。
- 标头在从一条消息到下一条消息的过程中通常非常相似,但仍然在连接之间重复。
- 尽管 HTTP/1.1 有 管道,但它在大多数浏览器中默认情况下未启用,并且不允许进行多路复用(即并发发送请求)。需要在同一个服务器上打开多个连接才能并发发送请求;而热 TCP 连接比冷连接效率更高。
HTTP/2 引入了额外的步骤:它将 HTTP/1.x 消息划分为嵌入在流中的帧。数据帧和标头帧是分开的,这允许标头压缩。可以将多个流组合在一起,这个过程称为多路复用,从而更有效地利用底层 TCP 连接。
HTTP 帧现在对 Web 开发人员透明。这是 HTTP/2 中在 HTTP/1.1 消息和底层传输协议之间添加的额外步骤。Web 开发人员使用的 API 无需进行任何更改即可利用 HTTP 帧;当浏览器和服务器都支持时,HTTP/2 将自动启用并使用。
结论
HTTP 消息是使用 HTTP 的关键;它们的结构很简单,并且具有很高的可扩展性。HTTP/2 帧机制在不从根本上修改 HTTP/1.x 语法的情况下,在 HTTP/1.x 语法和底层传输协议之间添加了一个新的中间层:在经过验证的机制之上构建。