凌云的博客

行胜于言

HTTP 发展史

分类:network| 发布时间:2025-01-02 17:42:00

概述

HTTP(超文本传输协议)是万维网的基础协议。 它由蒂姆·伯纳斯-李(Tim Berners-Lee)及其团队在1989年至1991年期间开发完成。 HTTP 经过多次演变,始终保持了其简洁性,同时也塑造了其灵活性。

本文简述了 HTTP 如何从一个用于在半信任实验室环境中交换文件的协议,发展成为一个现代互联网网络,能够传输高分辨率图像、视频,甚至3D 内容。

万维网的发明

1989年,在CERN工作时,蒂姆·伯纳斯-李(Tim Berners-Lee)提出了一个构建超文本系统的提案,该系统基于互联网。 最初称为“Mesh”,后来在1990年实施过程中更名为“World Wide Web”。 这个系统建立在现有的TCP和IP协议之上,包含了四个基本构件:

  • 一个用来表示超文本文档的文本格式,超文本标记语言(HTML)。
  • 一个用来交换超文本文档的简单协议,超文本传输协议(HTTP)。
  • 一个显示(以及编辑)超文本文档的客户端,即网络浏览器。第一个网络浏览器被称为 WorldWideWeb。
  • 一个服务器用于提供可访问的文档,即 httpd 的前身。

这四个部分完成于 1990 年底,且第一批服务器已经在 1991 年初在 CERN 以外的地方运行了。 1991 年 8 月 16 日,Tim Berners-Lee 在公开的超文本新闻组上发表的文章被视为是万维网公共项目的开始。

HTTP 在应用的早期阶段非常简单,后来被称为 HTTP/0.9,有时也叫做单行(one-line)协议。

HTTP/0.9 – 单行协议

HTTP的初始版本没有版本号;后来被称为0.9,以便与后来的版本区分开来。 HTTP/0.9 极其简单:请求由一行构成,且以唯一的请求方法 GET 开始,后跟资源的路径。 由于一旦连接到服务器,协议、服务器和端口不再需要,因此完整的 URL 不包含在请求中。

请求示例:

GET /my-page.html

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

响应示例:

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

与后来的版本不同,HTTP/0.9 没有 HTTP 头部。 这意味着只能传输 HTML 文件。没有状态码或错误码。 如果出现问题,则会生成一个特定的 HTML 文件,文件中包含问题的描述,供人工阅读。

HTTP/1.0 – 构建可扩展性

由于 HTTP/0.9 协议的应用十分有限,浏览器和服务器迅速扩展内容使其用途更广:

协议版本信息现在会随着每个请求发送(HTTP/1.0 被追加到了 GET 行)。

状态码会在响应开始时发送,使浏览器能了解请求执行成功或失败,并相应调整行为(如更新或使用本地缓存)。

引入了 HTTP 标头的概念,无论是对于请求还是响应,允许传输元数据,使协议变得非常灵活,更具扩展性。

在新 HTTP 标头的帮助下,具备了传输除纯文本 HTML 文件以外其他类型文档的能力(凭借 Content-Type 标头)。

一个典型的请求看起来就像这样:

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

200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
一个包含图片的页面
  <IMG SRC="/myimage.gif">
</HTML>

接下来是第二个连接,请求获取图片(并具有相同的响应):

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

200 OK
Date: Tue, 15 Nov 1994 08:12:32 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/gif
(这里是图片内容)

在 1991-1995 年,这些新扩展并没有被引入到标准中以促进协助工作,而仅仅作为一种尝试。 服务器和浏览器添加这些新扩展功能,但出现了大量的互操作问题。 直到 1996 年 11 月,为了解决这些问题,一份新文档(RFC 1945)被发表出来,用以描述如何操作实践这些新扩展功能。

文档 RFC 1945 定义了 HTTP/1.0,但它只是草案,不是官方标准。

HTTP/1.1——标准化的协议

HTTP/1.0 多种不同的实现方式在实际运用中显得有些混乱。 自 1995 年开始,即 HTTP/1.0 文档发布的下一年,就开始修订 HTTP 的第一个标准化版本。 在 1997 年初,HTTP1.1 标准发布,就在 HTTP/1.0 发布的几个月后。

HTTP/1.1 消除了大量歧义内容并引入了多项改进:

  • 连接可以复用,节省了多次打开 TCP 连接加载网页文档资源的时间。
  • 增加管线化技术,允许在第一个应答被完全发送之前就发送第二个请求,以降低通信延迟。
  • 支持响应分块。
  • 引入额外的缓存控制机制。
  • 引入内容协商机制,包括语言、编码、类型等。并允许客户端和服务器之间约定以最合适的内容进行交换。
  • 凭借 Host 标头,能够使不同域名配置在同一个 IP 地址的服务器上。

一个典型的请求流程,所有请求都通过一个连接实现,看起来就像这样:

GET /zh-CN/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: zh-CN,zh;q=0.9
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/zh-CN/docs/Glossary/CORS-safelisted_request_header

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: zh-CN,zh;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/zh-CN/docs/Glossary/CORS-safelisted_request_header

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 在 1997 年 1 月以 RFC 2068 文件发布。

HTTP/1.1 的扩展

由于 HTTP 协议的可扩展性使得创建新的头部和方法是很容易的。 即使 HTTP/1.1 协议进行过两次修订,RFC 2616 发布于 1999 年 6 月,而另外两个文档 RFC 7230-RFC 7235 发布于 2014 年 6 月(在 HTTP/2 发布之前)。HTTP/1.1 协议已经稳定使用超过 15 年了。

HTTP 用于安全传输

HTTP 最大的变化发生在 1994 年底。HTTP 在基本的 TCP/IP 协议栈上发送信息,网景公司(Netscape Communication)在此基础上创建了一个额外的加密传输层:SSL。 SSL 1.0 没有在公司以外发布过,但 SSL 2.0 及其后继者 SSL 3.0 允许通过加密来保证服务器和客户端之间交换消息的真实性,来创建电子商务网站。

SSL 在标准化道路上最终成为了 TLS。

RESTful

在 2000 年,一种新的使用 HTTP 的模式被设计出来:具象状态传输(representational state transfer) (或者说 REST)。

由 API 发起的操作不再通过新的 HTTP 方法传达,而只能通过使用基本的 HTTP / 1.1 方法访问特定的 URI。 这允许任何 Web 应用程序通过提供 API 以允许查看和修改其数据,而无需更新浏览器或服务器。 所有需要的内容都被嵌入到由网站通过标准 HTTP/1.1 提供的文件中。

REST 模型的缺点在于每个网站都定义了自己的非标准 RESTful API,并对其进行了全面的控制。

RESTful API 在 2010 年变得非常流行。

自 2005 年以来,可用于 Web 页面的 API 大大增加,其中几个 API 为特定目的扩展了 HTTP 协议,大部分是新的特定 HTTP 头:

  • Server-sent events,服务器可以偶尔推送消息到浏览器。
  • WebSocket,一个新协议,可以通过升级现有 HTTP 协议来建立。

HTTP/2

这些年来,网页愈渐变得的复杂,甚至演变成了单页应用,可见媒体的播放量,增进交互的脚本大小也增加了许多:更多的数据通过 HTTP 请求被传输。

HTTP/1.1 链接需要请求以正确的顺序发送,理论上可以用一些并行的链接(尤其是 5 到 8 个),带来的成本和复杂性堪忧。比如,HTTP 管线化(pipelining)就成为了 Web 开发的负担。

为此,在 2010 年早期,谷歌通过实践了一个实验性的 SPDY 协议。 这种在客户端和服务器端交换数据的替代方案引起了在浏览器和服务器上工作的开发人员的兴趣。 明确了响应数量的增加和解决复杂的数据传输,SPDY 成为了 HTTP/2 协议的基础。

HTTP/2 在 HTTP/1.1 有几处基本的不同:

  • HTTP/2 是二进制协议而不是文本协议。不再可读,也不可无障碍的手动创建,改善的优化技术现在可被实施。
  • 这是一个多路复用协议。并行的请求能在同一个链接中处理,移除了 HTTP/1.x 中顺序和阻塞的约束。
  • 压缩了标头。因为标头在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。
  • 其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。

在 2015 年 5 月正式标准化后,HTTP/2 取得了极大的成功,在 2022 年 1 月达到峰值,占所有网站的 46.9%(见这些统计数据)。

高流量的站点最迅速的普及,在数据传输上节省了可观的成本和支出。

这种迅速的普及率很可能是因为 HTTP2 不需要站点和应用做出改变:使用 HTTP/1.1 和 HTTP/2 对他们来说是透明的。

拥有一个最新的服务器和新点的浏览器进行交互就足够了。 只有一小部分群体需要做出改变,而且随着陈旧的浏览器和服务器的更新,而不需 Web 开发者做什么,用的人自然就增加了。

HTTP/3——基于 QUIC 的 HTTP

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。

总结

版本 发布年份 当前状态 2024年8月使用率 2024年8月支持情况
HTTP/0.9 1991 Obsolete 0 100%
HTTP/1.0 1996 Obsolete 0 100%
HTTP/1.1 1997 Standard 33.8% 100%
HTTP/2 2015 Standard 35.3% 66.2%
HTTP/3 2022 Standard 30.9% 30.9%

参考