一、版本演进时间线
1991 ──▶ HTTP/0.9 (只有 GET,无头部)
1996 ──▶ HTTP/1.0 (引入头部、状态码、POST,短连接)
1997 ──▶ HTTP/1.1 (持久连接、Host、缓存、管道化)
2015 ──▶ HTTP/2 (二进制、多路复用、HPACK、Server Push)
2022 ──▶ HTTP/3 (基于 QUIC/UDP,内置 TLS 1.3,连接迁移)
二、各版本详解与对比
1. HTTP/0.9(1991)------ 协议的雏形
特点:
- 只有 GET 方法。
- 无请求头、无响应头,纯文本传输。
- 无状态码,服务器出错只能传 HTML 报错页。
- 一次请求一个 TCP 连接,响应完立即关闭。
请求示例:
GET /index.html
(就这一行,没有版本号、没有 Host、没有头部)
2. HTTP/1.0(1996, RFC 1945)------ 标准化的起点
新增特性:
- 引入 POST、HEAD 方法。
- 引入 请求/响应头(Header),可传元数据(Content-Type、Content-Length)。
- 引入 状态码(200、404、500 等)。
- 引入 Content-Type,支持传输图片、视频等非文本。
致命缺陷:
- 短连接:每次请求都新建 TCP 连接,三次握手开销巨大。
- 无 Host 头部:一个 IP 只能对应一个域名,无法做虚拟主机(一个服务器托管多个网站)。
3. HTTP/1.1(1997, RFC 2616;2014 修订 RFC 7230-7235)------ 统治互联网 20 年的版本
核心改进:
| 特性 | 说明 |
|---|---|
| 持久连接(Keep-Alive) | 默认不关闭 TCP 连接,可复用传输多个请求/响应,减少握手开销。 |
| Host 头部 | 请求头必须带 Host: www.example.com,支持虚拟主机,一台服务器托管 N 个域名。 |
| 管道化(Pipelining) | 允许连续发送多个请求,无需等前一个响应。但响应必须按请求顺序返回,队头阻塞严重,浏览器默认禁用。 |
| 分块传输(Chunked) | Transfer-Encoding: chunked,服务器边生成边传,无需预先知道 Content-Length(适合动态内容)。 |
| 缓存控制 | 引入 Cache-Control、ETag、Last-Modified,精细化缓存策略。 |
| 范围请求(Range) | 支持断点续传,只请求资源的一部分(如视频拖动进度条)。 |
| 新增方法 | PUT、DELETE、OPTIONS、TRACE、CONNECT。 |
遗留问题:
- 队头阻塞(Head-of-Line Blocking):虽然 TCP 连接复用了,但请求/响应必须串行排队,前一个阻塞,后面的全等。
- 头部冗余:每次请求都重复发送大量相同头部(Cookie、User-Agent 等),浪费带宽。
- 明文传输:无强制加密。
4. HTTP/2(2015, RFC 7540)------ 性能革命
HTTP/2 不是 HTTP/1.2,而是基于 SPDY 协议的重设计 ,核心目标是解决 HTTP/1.1 的性能瓶颈。
核心特性:
| 特性 | 说明 |
|---|---|
| 二进制分帧(Binary Framing) | 不再传输纯文本,而是将数据拆分为二进制帧(Headers Frame、Data Frame),更高效、更不易出错。 |
| 多路复用(Multiplexing) | 一个 TCP 连接上可同时传输多个请求/响应,互相独立、交错发送,彻底解决 HTTP 层的队头阻塞。 |
| 头部压缩(HPACK) | 使用静态表、动态表和哈夫曼编码压缩头部,减少重复头部传输(如 Cookie 从几 KB 降到几十字节)。 |
| 服务器推送(Server Push) | 服务器可主动推送资源(如 HTML 请求后,服务器主动推送 CSS/JS),减少客户端等待。 |
| 流优先级(Stream Priority) | 客户端可指定哪个资源优先传输(如先传 CSS,后传图片)。 |
HTTP/2 的局限:
- 基于 TCP ,无法解决 TCP 层的队头阻塞:如果某个 TCP 包丢失,该连接上所有 HTTP/2 的 Stream 都必须等待重传。
- TLS 不是强制,但主流浏览器只支持 HTTPS 下的 HTTP/2。
- Server Push 常被滥用,实际收益有限,HTTP/3 中已废弃。
5. HTTP/3(2022, RFC 9114)------ 基于 QUIC 的未来
HTTP/3 不再基于 TCP,而是基于 QUIC(UDP),这是最大、最本质的变化。
核心特性:
| 特性 | 说明 |
|---|---|
| 基于 QUIC(UDP) | 传输层从 TCP 切换到 UDP,在用户态实现可靠传输、流控、拥塞控制。 |
| 彻底解决队头阻塞 | QUIC 内部多路复用基于独立 Stream,每个 Stream 有独立序列号。Stream A 丢包只阻塞 A,不影响 B。 |
| 内置 TLS 1.3 | 握手与连接建立合并,1-RTT (首次)或 0-RTT(后续),大幅降低延迟。 |
| 连接迁移 | 用 Connection ID 标识连接,IP 或端口变化(如 Wi-Fi 切 4G)连接不中断。 |
| Server Push 移除 | 实践中收益有限,HTTP/3 不再支持。 |
| 头部压缩(QPACK) | 类似 HPACK,但针对 QUIC 的不可靠传输做了调整(动态表更新独立)。 |
三、核心差异汇总表
| 维度 | HTTP/1.0 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|---|
| 传输层 | TCP | TCP | TCP | QUIC (UDP) |
| 连接方式 | 短连接 | 持久连接(Keep-Alive) | 单一长连接 + 多路复用 | QUIC 连接 + 多路复用 |
| 数据格式 | 纯文本 | 纯文本 | 二进制分帧 | 二进制分帧 |
| 队头阻塞 | 严重(串行) | 严重(管道化未解决) | HTTP 层解决,TCP 层仍存在 | 彻底解决 |
| 头部压缩 | 无 | 无 | HPACK | QPACK |
| 多路复用 | 无 | 无(管道化废弃) | 有 | 有(Stream 独立) |
| 服务器推送 | 无 | 无 | 有 | 无(移除) |
| 加密 | 可选 | 可选 | 事实强制(HTTPS) | 内置 TLS 1.3 |
| 握手延迟 | 2-3 RTT | 2-3 RTT | 2-3 RTT | 1-RTT / 0-RTT |
| 连接迁移 | 无 | 无 | 无 | 支持 |
| 虚拟主机 | 不支持 | Host 头部支持 | 支持 | 支持 |
四、关键概念辨析
1. HTTP/1.1 的 Pipelining 为什么失败了?
- 它允许连续发多个请求,但响应必须严格按请求顺序返回。
- 如果第一个请求处理慢,后面所有响应都被阻塞(队头阻塞)。
- 浏览器实现复杂且收益低,现代浏览器默认禁用。
2. HTTP/2 的多路复用为什么还有队头阻塞?
- HTTP/2 解决了应用层的队头阻塞(多个请求可以并行)。
- 但它底层仍是 TCP,TCP 是单条字节流。如果某个 TCP 包丢失,该连接上所有 Stream 都必须等它重传。
- 这是 HTTP/3 改用 QUIC 的根本原因。
3. HTTP/3 的 QPACK 与 HTTP/2 的 HPACK 有何不同?
- HPACK 依赖 TCP 的有序传输,动态表更新是同步的。
- QUIC 基于 UDP,包可能乱序或丢失。QPACK 将动态表更新放在独立的 单向 Stream 中,避免头部解码被阻塞。
五、常见问题
Q1:HTTP/1.1 如何优化性能?HTTP/2 又如何优化?
- HTTP/1.1:域名分片(开多个子域名突破浏览器并发限制)、雪碧图(合并图片)、资源内联/合并、Keep-Alive。
- HTTP/2:多路复用(一个连接传所有资源)、头部压缩、服务器推送、二进制分帧。
Q2:HTTP/2 和 HTTP/3 最核心的区别是什么?
- HTTP/2 基于 TCP ,HTTP/3 基于 QUIC(UDP)。
- HTTP/3 解决了 TCP 层的队头阻塞,支持连接迁移,内置 TLS 1.3,握手更快。
Q3:为什么 HTTP/3 选择 UDP 而不是改进 TCP?
- TCP 实现在操作系统内核中,全球几十亿台设备升级内核几乎不可能(协议僵化)。
- UDP 在用户态实现,可以像更新 App 一样迭代协议(QUIC 是用户态协议)。
Q4:HTTP/2 的 Server Push 为什么被 HTTP/3 移除?
- 实践中常被滥用,服务器推送了客户端不需要的资源,浪费带宽。
- 现代前端有 HTTP 缓存、Service Worker、预加载(
<link rel="preload">),Server Push 收益有限。
六、总结
HTTP/0.9 是婴儿,HTTP/1.0 是少年,HTTP/1.1 是壮年统治了 20 年,HTTP/2 是性能革命但受 TCP 拖累,HTTP/3 是换道超车------彻底抛弃 TCP,用 QUIC 重新定义传输层。
演进主线只有一条:连接复用 → 并行传输 → 彻底消除阻塞 → 更低的延迟。