HTTP 消息

HTTP 消息是服务器和客户端之间交换数据的途径。消息分为两种:请求,由客户端发送,用于触发服务器上的操作;以及响应,即来自服务器的答案。

Web 开发人员,或网站管理员,很少自己编写这些文本形式的 HTTP 消息:软件、Web 浏览器、代理或 Web 服务器会执行此操作。它们通过配置文件(针对代理或服务器)、API(针对浏览器)或其他接口提供 HTTP 消息。

From a user-, script-, or server- generated event, an HTTP/1.x msg is generated, and if HTTP/2 is in use, it is binary framed into an HTTP/2 stream, then sent.

HTTP 请求和响应具有相似的结构,由以下部分组成:

  1. 起始行,描述要执行的请求,或描述其成功或失败的状态。这始终是单行。
  2. 一组可选的HTTP 标头,用于指定请求,或描述消息中包含的正文。
  3. 一个空行,表示请求的所有元信息已发送。
  4. 一个可选的正文,包含与请求相关联的数据(如 HTML 表单的内容),或与响应相关联的文档。正文的存在及其大小由起始行和 HTTP 标头指定。

HTTP 消息的起始行和 HTTP 标头统称为请求的头部,之后包含其内容的部分称为正文

Requests and responses share a common structure in HTTP

HTTP 请求

请求行

注意:在请求中,起始行称为“请求行”。

HTTP 请求是由客户端发送的消息,用于在服务器上发起操作。它们的请求行包含三个元素:

  1. HTTP 方法,动词(如 GETPUTPOST)或名词(如 HEADOPTIONS),描述要执行的操作。例如,GET 表示应获取资源,而 POST 表示将数据推送到服务器(创建或修改资源,或生成要发回的临时文档)。
  2. 请求目标,通常是 URL,或协议、端口和域的绝对路径,通常由请求上下文确定。此请求目标的格式因不同的 HTTP 方法而异。它可以是:
    • 绝对路径,最后以 '?' 和查询字符串结尾。这是最常见的形式,称为原点形式,并用于 GETPOSTHEADOPTIONS 方法。
      • 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,称为绝对形式,主要用于连接到代理时使用 GETGET 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
  3. HTTP 版本,它定义了剩余消息的结构,充当响应中预期使用的版本的指示器。

标头

HTTP 标头 来自请求,遵循与 HTTP 标头相同的基本结构:一个不区分大小写的字符串,后跟一个冒号 (':') 和一个结构取决于标头类型的值。整个标头,包括其值,都是一行,可以很长。

请求中可以出现许多不同的标头。它们可以分为几个组:

Example of headers in an HTTP request

正文

响应的最后一部分是正文。并非所有响应都包含正文:如果响应的状态码足以回答请求,而无需包含消息 内容(如 201 Created204 No Content),则通常不包含正文。

正文可以大体上分为两类:

HTTP 响应

状态行

注意:在响应中,起始行称为“状态行”。

HTTP 响应的起始行,称为状态行,包含以下信息:

  1. 协议版本,通常是 HTTP/1.1,但也可以是 HTTP/1.0
  2. 状态码,指示请求成功或失败。常见的状态码有 200404302
  3. 状态文本。简短的纯信息文本描述,用于帮助人类理解 HTTP 消息。

典型的状态行如下所示:HTTP/1.1 404 Not Found

标头

HTTP 标头 对于响应,遵循与任何其他标头相同的结构:一个不区分大小写的字符串,后跟一个冒号 (':') 和一个结构取决于标头类型的值。整个标头,包括其值,都显示为一行。

响应中可以出现许多不同的标头。它们可以分为几个组:

Example of headers in an HTTP response

正文

响应的最后一部分是正文。并非所有响应都包含正文:如果响应的状态码足以回答请求,而无需包含内容(如 201 Created204 No Content),则通常不包含正文。

正文可以大体上分为三类:

  • 单资源正文,由一个已知长度的单个文件组成,由两个标头定义:Content-TypeContent-Length
  • 单资源正文,由一个未知长度的单个文件组成,通过块编码,Transfer-Encoding 设置为 chunked
  • 多资源正文,由多部分正文组成,每个部分包含不同的信息部分。这些相对罕见。

HTTP/2 帧

HTTP/1.x 消息在性能方面存在一些弊端:

  • 标头与正文不同,未压缩。
  • 标头在从一条消息到下一条消息的过程中通常非常相似,但仍然在连接之间重复。
  • 尽管 HTTP/1.1 有 管道,但它在大多数浏览器中默认情况下未启用,并且不允许进行多路复用(即并发发送请求)。需要在同一个服务器上打开多个连接才能并发发送请求;而热 TCP 连接比冷连接效率更高。

HTTP/2 引入了额外的步骤:它将 HTTP/1.x 消息划分为嵌入在流中的帧。数据帧和标头帧是分开的,这允许标头压缩。可以将多个流组合在一起,这个过程称为多路复用,从而更有效地利用底层 TCP 连接。

HTTP/2 modifies the HTTP message to divide them in frames (part of a single stream), allowing for more optimization.

HTTP 帧现在对 Web 开发人员透明。这是 HTTP/2 中在 HTTP/1.1 消息和底层传输协议之间添加的额外步骤。Web 开发人员使用的 API 无需进行任何更改即可利用 HTTP 帧;当浏览器和服务器都支持时,HTTP/2 将自动启用并使用。

结论

HTTP 消息是使用 HTTP 的关键;它们的结构很简单,并且具有很高的可扩展性。HTTP/2 帧机制在不从根本上修改 HTTP/1.x 语法的情况下,在 HTTP/1.x 语法和底层传输协议之间添加了一个新的中间层:在经过验证的机制之上构建。