在准备面试题的过程中,发现我对HTTP的演变过程知之甚少,要是被问到了只能说出一点,估计要栽了,于是赶紧查漏补缺。
HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最广泛的协议之一,它的发展史几乎就是互联网发展史的缩影。从最初的简单文本传输到如今的高效、安全、多功能的通信协议,HTTP经历了多个版本的演进。
HTTP/0.9:最初的简单协议
HTTP/0.9是HTTP协议的第一个版本。它的设计非常简单,仅支持最基本的功能:
- 只支持GET方法:客户端只能向服务器请求资源,无法发送其他类型的数据。
- 无头部信息,甚至没有状态码:请求和响应都不包含元数据(如内容类型、编码等)。
- 仅支持纯文本:响应内容只能是HTML格式,无法传输图片、视频等其他类型的数据。
- 请求完成后立即关闭连接。
尽管HTTP/0.9功能极其有限,但在当时满足了传输静态 HTML 文档的需求。它为后续的 HTTP 协议(如 HTTP/1.0、HTTP/1.1)的发展奠定了坚实的基础,也反映了互联网早期的技术现状。。
HTTP/1.0
随着Web的快速发展,HTTP/0.9的功能已经无法满足需求。HTTP/1.0引入了以下重要特性:
- 新增了两种方法:
POST、HEAD。 - 引入了头部(Headers),允许传输元数据(如内容类型、编码等)。
- 状态码:引入了多种状态码(如200 OK, 404 Not Found等)来表示请求处理的结果。
- 支持多种内容格式(如图片、视频等)。
- 响应头中的
Content-Type指明服务器返回的资源类型,告诉客户端如何处理接收到的数据。 - 请求头中的
Content-Type告诉服务器请求体的数据类型,确保服务器能够正确解析客户端发送的数据。而Accept头则表明客户端希望接收的响应数据类型。
- 响应头中的
HTTP 1.0 浏览器与服务器只保持短暂的连接,每次请求都需要与服务器建立一个TCP连接。
服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求
简单来讲,每次与服务器交互,都需要新开一个连接
关键点:
- HTTP/1.0 默认连接行为是 非持久连接(即每个请求/响应对使用不同的 TCP 连接)。
- 通过
Connection: keep-alive头字段,HTTP/1.0 可以开启持久连接,允许在同一连接上发送多个请求和响应。 - 直到 HTTP/1.1,持久连接才成为 默认行为,并且在 HTTP/1.1 中 所有连接都是持久连接,除非客户端或服务器显式要求关闭连接(通过
Connection: close)。
HTTP/1.1
为了解决HTTP/1.0中的性能问题,HTTP/1.1版本于进行了多方面的优化。最重要的改进包括:
- 持久连接(Keep-Alive) :HTTP/1.1引入了持久连接的概念,即一个TCP连接可以被多个HTTP请求/响应复用。这显著减少了由于频繁建立和断开TCP连接所带来的开销。客户端与服务器之间的连接可以保持开放,避免了每次请求都重新建立连接的成本。
- 管道化(Pipelining) :HTTP/1.1支持管道化技术,即客户端可以在等待第一个请求的响应时,继续发送后续请求。这种方式可以提高通信效率,尤其是在需要发起多个请求的情况下。然而,管道化也带来了“对头阻塞”的问题,即如果前一个请求未完成,后续的请求就必须等待,导致延迟增加。
- 更多的头部信息支持:HTTP/1.1还引入了更多的头部信息和控制字段,例如:
Content-Length、Transfer-Encoding、Host等。这些新字段使得协议更具扩展性。 - 缓存机制:引入了更强大的缓存控制(如Cache-Control、ETag等)。
- 分块传输编码:支持流式传输大文件。
- 虚拟主机支持:通过Host头部支持多个域名共享同一个IP地址。
- 加了其他的请求方法:
put、delete、options..
Keep-Alive 和 管道化的区别
| 特性 | Keep-Alive | 管道化(Pipelining) |
|---|---|---|
| 请求发送方式 | 客户端必须等待前一个请求的响应返回后,才能发送下一个请求。 | 客户端可以连续发送多个请求,无需等待响应。 |
| 响应顺序 | 响应顺序与请求顺序一致。 | 响应顺序必须与请求顺序严格一致。 |
| 队头阻塞问题 | 无队头阻塞问题。 | 存在队头阻塞问题。 |
| 实现复杂度 | 简单,广泛支持。 | 复杂,实际应用较少。 |
| 性能优化 | 减少了TCP连接的开销。 | 进一步减少了延迟,但受限于队头阻塞。 |
HTTP/2
HTTP/2于2015年发布,引入了多项革命性的改进:
- 多路复用
- 并行传输:在同一个连接上可以同时处理多个请求和响应,且相互之间不受影响。
- 解决队头阻塞:通过为每个请求分配唯一的流ID,每个响应不用按顺序返回,避免了HTTP/1.1的队头阻塞问题。
- 二进制分帧
在 HTTP/2 中,所有的请求和响应都被分成了一个个小的 数据帧(Frame),,意味着HTTP/2 不再使用纯文本格式(如 HTTP/1.x)来表示请求和响应 。
这些帧可以包含各种不同类型的数据,如请求头、请求体、响应头、响应体等。每个帧都是二进制编码的,且每个帧都有一个 帧头(Header) ,它提供了该帧的类型、长度等信息。帧数据可以在一个连接上并行地进行传输,而每个帧的顺序并不依赖于其他帧的顺序,这就是 多路复用 的基础。
-
服务器推送(Server Push)
- 主动推送:服务器可以主动向客户端发送数据,而不需要客户端发起请求。例如,服务器可以在客户端请求HTML页面时,主动推送相关的CSS和JavaScript文件。
- 实际案例:在Web页面加载时,服务器推送可以显著减少延迟,提升用户体验。
-
头部压缩
- HPACK算法:通过压缩头部字段,减少了传输开销。
HTTP/3
-
基本特性:HTTP/3是基于QUIC协议的,QUIC(Quick UDP Internet Connections)是由Google提出的一种新的传输协议,它基于UDP而非TCP,目的是进一步减少连接和传输延迟,特别是在移动设备和高丢包率的网络环境下表现更好。
-
协议特性:
- 基于QUIC:HTTP/3基于QUIC协议,而QUIC本身是一个基于UDP的协议,解决了TCP在多次握手、重传等方面的瓶颈。
- 零连接建立:QUIC支持零连接建立,即客户端可以在首次连接时快速发送数据,减少了传统TCP连接的延迟。
- 多路复用:HTTP/3继续使用HTTP/2的多路复用技术,但由于使用UDP而非TCP,它避免了TCP的队头阻塞问题。
- 加密:QUIC协议本身强制加密,所有的HTTP/3通信默认启用TLS加密,增强了安全性。
- 更低的延迟:QUIC的快速连接建立和恢复机制减少了因丢包导致的延迟,提高了高丢包和高延迟网络环境下的表现。
总结
HTTP1.0:
- 浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接
HTTP1.1:
- 引入了持久连接,即TCP连接默认不关闭,可以被多个请求复用
- 在同一个TCP连接里面,客户端可以同时发送多个请求
- 虽然允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按次序进行的,服务器只有处理完一个请求,才会接着处理下一个请求。如果前面的处理特别慢,后面就会有许多请求排队等着
- 新增了一些请求方法
- 新增了一些请求头和响应头
HTTP2.0:
- 采用二进制格式而非文本格式
- 完全多路复用,而非有序并阻塞的、只需一个连接即可实现并行
- 使用报头压缩,降低开销
- 服务器推送
| 特性 | HTTP/0.9 | HTTP/1.0 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|---|---|
| 请求方法 | 仅支持GET | GET, POST, HEAD等 | 增加PUT、DELETE等 | 与1.1相同 | 与2相同 |
| 响应格式 | 仅HTML页面 | 增加了头部信息 | 支持持久连接 | 二进制格式 | 基于QUIC协议 |
| 连接方式 | 每次请求都要连接 | 每个请求/响应一个连接 | 持久连接(keep-alive) | 多路复用 | 更高效的连接管理 |
| 头部压缩 | 无 | 无 | 无 | HPACK压缩 | QUIC内建加密和压缩 |
| 服务器推送 | 无 | 无 | 无 | 支持 | 支持 |
| 性能优化 | 无 | 无 | 管道化、缓存控制 | 更高效的多路复用 | 更低延迟、更少阻塞 |
| 安全性 | 无 | 无 | 有SSL支持 | 强制TLS加密 | 默认TLS加密 |
参考文章