HTTP 演变

HTTP(超文本传输协议)是万维网的基础协议。 HTTP 由蒂姆·伯纳斯·李及其团队在 1989 年至 1991 年间开发,它经历了许多变化,这些变化有助于保持其简单性,同时塑造其灵活性。继续阅读以了解 HTTP 如何从一个旨在在一个半信任的实验室环境中交换文件的协议发展成为一个现代的互联网迷宫,它以高分辨率和 3D 传输图像和视频。

万维网的发明

1989 年,蒂姆·伯纳斯·李在欧洲核子研究组织工作期间,提出了在互联网上构建超文本系统的建议。它最初被称为Mesh,后来在 1990 年的实施过程中更名为万维网。它构建在现有的 TCP 和 IP 协议之上,由 4 个构建块组成

  • 一种用于表示超文本文档的文本格式,即超文本标记语言(HTML)。
  • 一种用于交换这些文档的简单协议,即超文本传输协议(HTTP)。
  • 一个用于显示(和编辑)这些文档的客户端,第一个名为WorldWideWeb 的网页浏览器。
  • 一个用于访问文档的服务器,httpd 的早期版本。

这四个构建块在 1990 年底完成,第一个服务器在 1991 年初运行在欧洲核子研究组织之外。1991 年 8 月 6 日,蒂姆·伯纳斯·李发布在公开的alt.hypertext 新闻组上。这现在被认为是万维网作为公共项目的正式开始。

在那些早期阶段使用的 HTTP 协议非常简单。它后来被称为 HTTP/0.9,有时也被称为单行协议。

HTTP/0.9 - 单行协议

HTTP 的初始版本没有版本号;后来被称为 0.9 以将其与以后的版本区分开来。HTTP/0.9 非常简单:请求由一行组成,并以唯一可能的方法GET 开头,后跟资源的路径。完整的 URL 没有包含在内,因为一旦连接到服务器,协议、服务器和端口就不再需要了。

http
GET /mypage.html

响应也非常简单:它只包含文件本身。

html
<html>
  A very simple HTML page
</html>

与随后的演变不同,没有 HTTP 标头。这意味着只能传输 HTML 文件。没有状态代码或错误代码。如果有问题,会生成一个特定的 HTML 文件,其中包含供人类理解的故障描述。

HTTP/1.0 - 构建可扩展性

HTTP/0.9 非常有限,但浏览器和服务器很快就使其变得更加通用

  • 版本信息在每个请求中发送(HTTP/1.0 附加到 GET 行)。
  • 响应的开头也会发送一个状态码行。这使得浏览器本身能够识别请求的成功或失败并相应地调整其行为。例如,以特定方式更新或使用其本地缓存。
  • 为请求和响应引入了 HTTP 标头的概念。元数据可以传输,协议变得非常灵活和可扩展。
  • 除了纯 HTML 文件之外,其他文档也可以通过Content-Type 标头传输。

在那个时候,一个典型的请求和响应看起来像这样

http
GET /mypage.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

HTTP/1.0 200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
A page with an image
  <IMG SRC="/myimage.gif">
</HTML>

后面跟着第二个连接,以及获取图像的请求(以及相应的响应)

http
GET /myimage.gif HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

HTTP/1.0 200 OK
Date: Tue, 15 Nov 1994 08:12:32 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/gif
(image content)

在 1991 年至 1995 年之间,这些都是通过尝试和查看的方式引入的。服务器和浏览器会添加一个功能,然后看看它是否会流行起来。互操作性问题很常见。为了解决这些问题,一份描述常见做法的信息文档于 1996 年 11 月发布。这被称为RFC 1945,并定义了 HTTP/1.0。

HTTP/1.1 - 标准化协议

与此同时,正式标准化正在进行中。这与 HTTP/1.0 的各种实现同时进行。HTTP 的第一个标准化版本 HTTP/1.1 于 1997 年初发布,仅比 HTTP/1.0 晚几个月。

HTTP/1.1 澄清了歧义并引入了许多改进

  • 连接可以重复使用,这节省了时间。它不再需要多次打开来显示嵌入在单个原始文档中的资源。
  • 添加了流水线处理。这允许在第一个请求的答案完全传输之前发送第二个请求。这降低了通信的延迟。
  • 还支持分块响应。
  • 引入了额外的缓存控制机制。
  • 引入了内容协商,包括语言、编码和类型。客户端和服务器现在可以就交换哪些内容达成一致。
  • 由于Host 标头,从同一 IP 地址托管不同域的能力允许服务器并置。

一个典型的请求流,全部通过一个单一连接,看起来像这样

http
GET /en-US/docs/Glossary/CORS-safelisted_request_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://mdn.org.cn/en-US/docs/Glossary/CORS-safelisted_request_header

HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding

(content)

GET /static/img/header-background.png HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://mdn.org.cn/en-US/docs/Glossary/CORS-safelisted_request_header

HTTP/1.1 200 OK
Age: 9578461
Cache-Control: public, max-age=315360000
Connection: keep-alive
Content-Length: 3077
Content-Type: image/png
Date: Thu, 31 Mar 2016 13:34:46 GMT
Last-Modified: Wed, 21 Oct 2015 18:27:50 GMT
Server: Apache

(image content of 3077 bytes)

HTTP/1.1 最初作为RFC 2068 于 1997 年 1 月发布。

二十多年的发展

HTTP 的可扩展性使得创建新的标头和方法变得容易。即使 HTTP/1.1 协议在两次修订中得到了完善,RFC 2616 于 1999 年 6 月发布,RFC 7230-RFC 7235 于 2014 年 6 月发布,在 HTTP/2 发布之前,它在 15 年以上的时间里非常稳定。HTTP/1.1 于 2022 年再次更新,更新为RFC 9110。不仅更新了 HTTP/1.1,而且所有 HTTP 都进行了修订,现在被拆分为以下文档:语义 (RFC 9110)、缓存 (RFC 9111) 应用于所有 HTTP 版本,以及 HTTP/1.1 (RFC 9112)、HTTP/2 (RFC 9113) 和 HTTP/3 (RFC 9114)。此外,该规范最终获得了互联网标准 (STD 97) 的地位,而在此之前它一直是提议的/草案标准。

使用 HTTP 进行安全传输

HTTP 最大的变化发生在 1994 年底。网络服务公司 Netscape Communications 没有将 HTTP 发送到基本的 TCP/IP 堆栈上,而是在其之上创建了一个额外的加密传输层:SSL。SSL 1.0 从未公开发布,但 SSL 2.0 及其后继者 SSL 3.0 允许创建电子商务网站。为此,它们对服务器和客户端之间交换的消息进行了加密并保证了其真实性。SSL 最终被标准化并成为 TLS。

在同一时期,很明显需要一个加密的传输层。网络不再是一个主要由学术界使用的网络,而是变成了一个广告商、随机个人和罪犯争夺尽可能多的私人数据的丛林。随着建立在 HTTP 之上的应用程序变得更加强大,并且需要访问地址簿、电子邮件和用户位置等私人信息,TLS 在电子商务用例之外变得必不可少。

将 HTTP 用于复杂应用程序

蒂姆·伯纳斯·李最初并没有将 HTTP 设想为一个只读介质。他想创建一个网络,人们可以在其中远程添加和移动文档——一种分布式文件系统。大约在 1996 年,HTTP 扩展到允许创作,并创建了一个名为 WebDAV 的标准。它发展到包括特定应用程序,例如用于处理地址簿条目的 CardDAV 和用于处理日历的 CalDAV。但所有这些 *DAV 扩展都存在一个缺陷:它们只有在服务器实施时才能使用。

在 2000 年,设计了一种使用 HTTP 的新模式:具象状态传输(或 REST)。API 并非基于新的 HTTP 方法,而是依赖于使用基本 HTTP/1.1 方法访问特定的 URI。这允许任何 Web 应用程序让 API 检索和修改其数据,而无需更新浏览器或服务器。所有必要的信息都嵌入到网站通过标准 HTTP/1.1 提供的文件中。REST 模型的缺点是每个网站都定义了自己的非标准 RESTful API,并且对它拥有完全控制权。这不同于 *DAV 扩展,在 *DAV 扩展中,客户端和服务器是互操作的。RESTful API 在 2010 年代变得非常普遍。

自 2005 年以来,更多 API 可用于网页。其中一些 API 为特定目的创建了 HTTP 协议的扩展

  • 服务器发送事件,其中服务器可以偶尔向浏览器推送消息。
  • WebSocket,一种可以通过升级现有 HTTP 连接来设置的新协议。

放宽 Web 的安全模型

HTTP 与网络安全模型(即 同源策略)是相互独立的。事实上,目前的网络安全模型是在 HTTP 诞生之后才开发出来的!多年来,在某些限制条件下,放松同源策略的某些限制被证明是有用的。服务器通过一组新的 HTTP 头部信息,向客户端传输放松这些限制的程度和时间。这些头部信息在 跨域资源共享 (CORS)内容安全策略 (CSP) 等规范中定义。

除了这些大型扩展之外,还添加了许多其他头部信息,有时仅供实验使用。值得注意的头部信息包括用于控制隐私的 "请勿跟踪" (DNT) 头部信息、X-Frame-OptionsUpgrade-Insecure-Requests,但还有很多其他的头部信息。

HTTP/2 - 更高性能的协议

多年来,网页变得越来越复杂。其中一些甚至本身就是应用程序。显示的视觉媒体也越来越多,增加交互性的脚本的体积和大小也增加了。通过越来越多的 HTTP 请求传输的数据量和大小也增加了,这给 HTTP/1.1 连接带来了更大的复杂性和开销。为了解决这个问题,谷歌在 2010 年代初期实施了一个实验性的协议 SPDY。这种在客户端和服务器之间交换数据的替代方式引起了浏览器和服务器开发人员的兴趣。SPDY 定义了响应能力的提升,并解决了重复数据传输的问题,为 HTTP/2 协议奠定了基础。

HTTP/2 协议与 HTTP/1.1 在以下几个方面有所不同。

  • 这是一个二进制协议,而不是文本协议。它不能手动读取和创建。尽管存在这个障碍,它允许实施改进的优化技术。
  • 这是一个多路复用协议。可以在同一连接上发出并行请求,从而消除 HTTP/1.x 协议的限制。
  • 它压缩头部信息。由于这些信息在多个请求中经常相似,这消除了传输数据的重复和开销。
  • 它允许服务器通过一种称为服务器推送的机制,将数据填充到客户端缓存中。

HTTP/2 协议于 2015 年 5 月正式标准化,其使用率在 2022 年 1 月达到顶峰,占所有网站的 46.9%(请参阅 这些统计数据)。高流量网站为了节省数据传输开销和后续预算,最先快速采用该协议。

这种快速采用可能是因为 HTTP/2 不需要对网站和应用程序进行更改。要使用它,只需要一个最新的与最新浏览器通信的服务器即可。只需要有限的几个组来触发采用,随着旧版浏览器和服务器版本的更新,使用率自然会提高,而无需网站开发人员进行大量的工作。

HTTP/2 之后的演变

HTTP 的可扩展性仍在用于添加新功能。值得注意的是,我们可以引用 2016 年出现的 HTTP 协议的新扩展。

  • Alt-Svc 的支持允许将给定资源的标识和位置分离。这意味着可以实现更智能的 CDN 缓存机制。
  • 引入 客户端提示 允许浏览器或客户端主动向服务器传达有关其需求和硬件限制的信息。
  • Cookie 头部信息中引入与安全相关的前缀有助于确保安全 Cookie 不会被篡改。

HTTP/3 - HTTP over QUIC

HTTP 的下一个主要版本 HTTP/3 具有与早期版本 HTTP 相同的语义,但使用 QUIC 而不是 TCP 作为传输层部分。截至 2022 年 10 月,26% 的网站都在使用 HTTP/3

QUIC 旨在为 HTTP 连接提供更低的延迟。与 HTTP/2 一样,它也是一个多路复用协议,但 HTTP/2 运行在单个 TCP 连接上,因此在 TCP 层处理的数据包丢失检测和重传可能会阻塞所有流。QUIC 在 UDP 上运行多个流,并为每个流独立地实施数据包丢失检测和重传,因此,如果发生错误,只有包含该数据包数据的流会被阻塞。

根据 RFC 9114 的定义,HTTP/3 受大多数主流浏览器支持,包括 Chromium(及其变体,如 Chrome 和 Edge)和 Firefox。