HTTP的发展史
前言
各种协议的标准化推动着互联网的普及,我们每天都在用HTTP、Web,其历史发展是怎么的?接下来文章希望对HTTP的发展史有个比较清晰的认识。
超文本与万维网
这里首先解释两个词,超文本和万维网。
超文本:英文 Hypertext,是一种内容组织和展示的方式,它定义了一种非线性的文本浏览方式。“超”是一种超链接的方式可以从一个信息点跳转到另一个;而“文本”是包括文字、图片、音视频等元素。概念在20世纪二三十年代提出。
万维网:英文 World Wide Web(WWW),万维网一开始不叫这个名,而是叫Mesh,1989年,由当时在CERN工作的Tim Berners-Lee博士写的一篇文章,关于建立一个通过网络传输超文本系统的报告,被命名为Mesh,在1990年项目实施期间更名万维网。
万维网包括四个部分:
- 表示超文本文档的文本格式,超文本标记语言(HTML)
- 交换超文本文档的简单协议,超文本传输协议(HTTP)
- 显示(及编辑)超文本文档的客户端,即网络浏览器
- 一个服务器用于提供可访问的文档,httpd前身
1990年底完成四部分的构建。其中的超文本传输协议HTTP,早期比较简单,被称为HTTP/0.9,有时也叫单行(one-line)协议。
HTTP协议的发展
根据OSI或TCP/IP模型,HTTP是建立在TCP、IP协议之上的协议。
HTTP/0.9 - 单行协议
起初没有版本概念,为了和后续的内容分开,定义为0.9版本。这个版本非常简单。
其特点如下:
- 请求由单行构成,后跟资源路径。如 GET /my.html
- 唯一的请求方式:GET
- 响应简单,仅包括HTML本身内容
请求响应如下:
// 请求
GET /my.html
// 响应
<html>
这是一个 HTML 页面
</html>
HTTP/1.0 - 可扩展性
HTTP进一步发展,提高了HTTP的扩展性,此时定义为HTTP/1.0版本。1991-1995年处于实验尝试阶段,到了1996年,在RFC1945中定义了HTTP/1.0,描述了如何操作实践这些扩展。
其特点如下:
- 在请求第一行最后增加协议版本,如HTTP/1.0
- 响应时返回状态码,表示请求成功或失败;可以区分控制错误和业务错误了
- 引入了HTTP 标头的概念,请求和响应都可以加,提供扩展性
- 有了标头,不仅可以传输文本,还可以是其它类型文档,如图片;可以区分元数据和业务数据了
- 默认情况下,使用的短连接模型
请求响应如下:
// 请求
GET /my.html HTTP/1.0
User-Agent:Mozilla/5.0
// 响应
200 OK
Date: Tue, 05 Dec 2023 15:14:47 GMT
Server: Google Frontend
Content-Type: text/html
<html>
这是一个文档页面
</html>
HTTP/1.1 - 标准化
在HTTP/1.0版本,很多地方并没有标准版,出现很多不同的实现。
例如:
1、在HTTP/1.0里有个不足的点是默认每次请求/响应都会进行一次TCP连接建立,不过在HTTP/1.0在后期实现上,有的浏览器引入了Connection: Keep-Alive
这个非标准的HTTP头实现一次TCP握手进行多次HTTP请求,以此实现长连接。但是有些代理服务器并不认识它。
支持HTTP/1.0长连接的服务器,也会返回
Connection: Keep-Alive
,具体长连接的时间由如响应头Keep-Alive: timeout=5, max=1000
决定。
2、还有对状态码的定义,不同的浏览器和服务器使用和解释也有所不同。
基于此,于1997年初,HTTP/1.1版本标准化协议发布,RFC2068文档,和HTTP/1.0相距仅几个月。
最新文档22年6月份发出的
1、“HTTP Semantics”:RFC9110、
2、“HTTP/1.1”:RFC9112。
HTTP/1.1消除了很多歧义,并引入了多项改进,其特点包括:
- 默认使用HTTP长连接,不需要指定
Connection: Keep-Alive
。明确Connection: close
时才关闭使用长连接。 - 增加管线化技术(pipeLining),允许在第一个请求未返回时发送第二个请求(不能在如POST等非幂等方法上使用pipeLining技术)
- 支持响应分块,不需要返回Content-Length,客户端也不会断开连接,知道块传递完
- 引入额外的缓存控制机制和内容协商机制
- 支持Host标头,应对多个Host绑定到同一个IP的情况,根据ip可以知道访问哪个服务器
请求响应如下:
// 请求
GET /zh-CN/docs/Glossary/Simple_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://developer.mozilla.org/zh-CN/docs/Glossary/Simple_header
// 响应
200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 06 Dec 2023 14:48:48 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Wed, 06 Dec 2023 14:48:48 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
(content)
这里解释下:管线化技术(pipeLining)和响应分块(chunked)
- 管线化技术(pipeLining):正常http是请求-应答模式,一个请求到一个结果回。有了管道化技术,客户端可以不用等上一个请求结果,紧接着发送下一个请求。但是服务端仍要按顺序处理请求和响应,客户端也要按请求顺序处理结果。那么如果服务器处理的慢,就会导致后续的请求阻塞,这便是“线头阻塞”(Head -of-Line Blocking)。可以通过新开tcp连接分开请求,但新开连接比较有限。
- 响应分块(chunked):它一种数据响应的编码格式。使用响应头
Transfer-Encoding
,可选值包括:chunked、compress、deflate、gzip、identity。可同时指定多个。使用chunked表示数据分块响应,此时不需要指定content-length
,通过长连接完成所有块的响应。
这两种技术在HTTP/2不使用了,使用多路复用。
HTTP/1.x版本下的几种连接模型:
从左到右依次:
- 短连接模型:HTTP/1.0默认行为;或 HTTP/1.1手动开启
Connection: close
- 长连接模型:HTTP/1.1默认行为;或 HTTP/1.0后期手动开启
Connection: keep-alive
- HTTP流水线:HTTP/1.1扩展,受制于必须顺序响应模式的队头阻塞(HOL),基本上浏览器不启用了,现在也已经被HTTP/2更好的算法取到。
HTTP/1.1稳定使用了超过15年。
基于HTTP的发展 - 插曲
HTTP发展期间,衍生了些扩展。
- 1994年底,网景公司创建了一个额外的加密传输层:SSL,并推出HTTPS,通过加密保证服务器与客户端之间交换消息的真实性。最终1999年IETF将SSL标准化,形成TLS(传输层安全协议,Transport Layer Security),该协议于应用层与传输层协议之间。
- 2000年,一种新的使用HTTP的模式被设计出来:具象状态传输(REST)。通过基本的HTTP方法访问特定的URI,来向客户端提供数据。
- 2008年,出现WebSocket协议,2011年由IETF标准化,支持服务器浏览器双向传输。
HTTP/2 - 更优异表现
网页越来越复杂,同一个页面可能涉及很多资源需要加载,需要更多的HTTP请求被传输。如果仍用HTTP/1.1同一TCP连接请求需要顺序处理,性能让人堪忧。
在HTTP/2的特点如下:
- HTTP/2使用的是二进制协议,不再是文本协议,提高数据传输效率。
- 支持多路复用,并行的请求不再受顺序和阻塞的限制,多个请求在一个TCP连接即可完成。实现多路复用是将请求数据分“帧”传输,不同的帧所属不同的"流",不同的流可以并行传输,流有编号对应着HTTP请求。
- 请求头压缩。通过引入“标头表”缓存机制,来减少多个请求-响应中重复的标头字段,如User-Agent、Accetp等。降低了网络开销,提高了传输效率。
HTTP/2于2015年正式标准化,发布补充文档RFC9113,2022年1月达到顶峰,占所有网站的46.9%。
HTTP/2的普及情况参考>
扩展一下:
这里再提一下,HTTP/2通过多路复用解决了HTTP/1.1中的队头阻塞(同一个TCP中响应请求需要顺序响应,属于应用层的队头阻塞),如下图所示:
区别:
1、HTTP/1.1使用文本协议,HTTP/2使用二进制协议。
2、HTTP/2返回的数据前有帧,使用steamId区分数据,这样请求就不用按顺序响应了。
但是阻塞仍在,HTTP/2的阻塞,是TCP的队头阻塞。如下图所示,如果出现丢包会导致TCP后续的包存于TCP缓冲区,等待重试成功,再给到应用层。例如图中包2丢失,包3会被阻塞,这是TCP层的队头阻塞。但它出现的概率远小于HTTP/1.1的队头阻塞。
图片来源参考
HTTP/3 - 基于QUIC
HTTP/3版本在传输层不使用TCP,而是UDP协议,通过QUIC(快速UDP互联网连接,Quick UDP Internet Connections)基于UDP协议实现,可同时允许多个独立的流,并单独为这些流做包丢失检测和重传,如果发生错误,不会导致阻止其它流,多流场景提高了性能。
虽然是基于UDP(用户数据报协议),但其实现数据重传、流量控制、加密与安全等保障了可靠传输。
前HTTP/3定义在RFC9114,已被大多数浏览器多支持,至2022年底,网站使用率已达26%。
通过下图可以看出,TCP没有流信息,QUIC可按流重传:
通过下图,可以看到协议栈的不同:
图片来源参考
总结
从1990年的HTTP/0.9版本实现,到1996年HTTP/1.0版本,再到1997发布的HTTP/1.1版本,再到2015年推出的HTTP/2,最后到今天HTTP/3。30年的时间,HTTP一直在发展。不得不说HTTP和其它协议一起带动着互联网的普及,2000年互联网慢慢被大家所熟知,推动电商平台等兴起;到2010年,手机的普及,推动移动互联的普及。技术的标准化,对推动技术发展、增强兼容性和促进全球互联网的增加起到至关重要的作用。
参考阅读:
HTTP的发展
HTTP/2: the difference between HTTP/1.1, benefits and how to use it
HTTP的前世今生
HOL Bloking