HTTP 协议发展详解:从 HTTP/1 到 HTTP/3
目录
- [HTTP 的背景](#HTTP 的背景)
- [HTTP 发展时间轴](#HTTP 发展时间轴)
- HTTP/1.0(1996)
- HTTP/1.1(1997)
- HTTP/2(2015)
- HTTP/3(2022)
- 发展总结表
- 连接与队头阻塞对比图
- 未来趋势
- [HTTP 版本与核心 RFC 对照表](#HTTP 版本与核心 RFC 对照表)
- [核心 RFC 文档详解](#核心 RFC 文档详解)
- 总结
一、HTTP 的背景
HTTP (HyperText Transfer Protocol,超文本传输协议)是万维网的基础通信协议,用于客户端(通常是浏览器)和服务器之间传输资源(HTML、图片、视频等)。它基于 TCP/IP 协议栈,工作在应用层。
协议栈中的位置:
链路层
网络层
传输层
应用层
HTTP / HTTPS
TCP
QUIC over UDP
IP
以太网等
| 层次 | HTTP/1.x、HTTP/2 使用 | HTTP/3 使用 |
|---|---|---|
| 应用层 | HTTP 语义 | HTTP 语义 |
| 传输层 | TCP | QUIC(基于 UDP) |
| 网络层 | IP | IP |
HTTP 发展时间轴
1996 HTTP/1.0 RFC 1945,首份正式标准,短连接 1997-1999 HTTP/1.1 RFC 2068/2616,Keep-Alive、Host、管道化 2014 HTTP/1.1 拆分 RFC 7230-7235,模块化定义 2015 HTTP/2 RFC 7540/7541,二进制分帧、多路复用、HPACK 2022 HTTP/3 RFC 9114,基于 QUIC,无 TCP 队头阻塞 2022 语义统一 RFC 9110-9113,跨版本统一语义 HTTP 协议演进时间轴
二、HTTP/1.0(1996)
2.1 特点
- 每个请求/响应对都需要建立一个新的 TCP 连接(短连接)。
- 没有持久连接支持,导致频繁的握手开销。
- 只支持基本的 GET、POST、HEAD 方法。
- 头部信息未经压缩,冗余大。
2.2 问题
- 性能低:每次请求都要重新建立连接。
- 无法有效利用带宽;多资源页面需要多次 TCP 握手与挥手。
2.3 HTTP/1.0 速查
| 项目 | 内容 |
|---|---|
| 方法 | GET、POST、HEAD |
| 典型状态码 | 200 OK、301 Moved Permanently、400 Bad Request、404 Not Found、500 Internal Server Error |
| 连接 | 默认短连接,请求完成即关闭 |
| 首部 | 无 Host,无压缩 |
三、HTTP/1.1(1997,RFC 2068 → RFC 2616 → RFC 7230+)
3.1 主要改进
- 持久连接(Keep-Alive):默认在同一 TCP 连接上发送多个请求/响应,减少握手次数。
- 管道化(Pipelining):客户端可在未收到前一个响应时发送后续请求,但服务器须按序返回,实际使用有限。
- 分块传输编码(Chunked Transfer Encoding):在未知 Content-Length 时仍可逐步发送实体。
- 更多方法:PUT、DELETE、OPTIONS、TRACE、CONNECT。
- Host 头:支持虚拟主机,单 IP 多域名。
3.2 问题
- 队头阻塞(HOL Blocking):管道化下仍须按请求顺序回包,前一个响应慢会拖慢后续所有响应。
- 单连接上仍是一请求一响应的逻辑;浏览器常通过多连接(如每域 6 个)来并行,带来连接数与队头阻塞的折中。
3.3 HTTP/1.1 与 1.0 连接对比
服务器 客户端 服务器 客户端 HTTP/1.0 短连接(3 个资源 = 3 次 TCP) HTTP/1.1 持久连接(1 次 TCP,多次请求) TCP 握手 GET /a 200 + 关闭 TCP 握手 GET /b 200 + 关闭 TCP 握手 GET /c 200 + 关闭 TCP 握手 GET /a 200 (保持连接) GET /b 200 (保持连接) GET /c 200 (保持连接)
四、HTTP/2(2015,RFC 7540)
4.1 目标
解决 HTTP/1.1 的队头阻塞与连接利用率问题:单连接上多路复用多个逻辑流。
4.2 核心技术
- 二进制分帧层:将 HTTP 消息拆成帧(Frame),在单 TCP 连接上复用。
- 多路复用:不同流的帧可交错发送,同一连接上并发多个请求/响应。
- 流优先级:客户端可为流指定优先级,优化关键资源顺序。
- 服务器推送:服务器可主动推送资源(PUSH_PROMISE),无需客户端先请求。
- HPACK 头部压缩:静态表 + 动态表 + Huffman,减少重复头部。
4.3 优势与局限
- 优势:页面加载延迟明显下降,尤其多小资源场景。
- 局限 :仍基于 TCP ,一旦发生丢包,TCP 重传会导致整条连接上所有流被阻塞(传输层队头阻塞)。
4.4 HTTP/2 帧类型速查
| 帧类型 | 方向 | 用途 |
|---|---|---|
| DATA | 双向 | 携带请求/响应体数据 |
| HEADERS | 双向 | 打开流并携带头部(可带 END_STREAM) |
| PRIORITY | 客户端→服务器 | 设置流优先级/依赖关系 |
| RST_STREAM | 双向 | 终止流 |
| SETTINGS | 双向 | 连接参数(如最大并发流、窗口大小) |
| PUSH_PROMISE | 服务器→客户端 | 声明即将推送的资源 |
| PING | 双向 | 保活与 RTT 测量 |
| GOAWAY | 双向 | 优雅关闭连接,停止新流 |
| WINDOW_UPDATE | 双向 | 流级/连接级流量控制窗口更新 |
五、HTTP/3(2022,RFC 9114)
5.1 目标
在传输层消除队头阻塞,并优化连接建立与移动网络下的体验。
5.2 核心技术
- 基于 QUIC:QUIC 跑在 UDP 上,由 IETF 标准化(RFC 9000),内建多路复用与加密。
- 每流独立丢包:丢包只影响该流,不影响其他流,无 TCP 式整连接阻塞。
- 更快建连 :QUIC 将传输与 TLS 1.3 结合,支持 0-RTT / 1-RTT 建立。
- 连接迁移:客户端 IP/端口变化(如 Wi-Fi ↔ 4G)时,通过 Connection ID 保持逻辑连接。
- 拥塞控制:在用户空间实现,便于迭代新算法。
5.3 优势与挑战
- 优势:弱网与高延迟下表现更好;默认 TLS 1.3,安全性高。
- 挑战:需服务器与中间设备支持 QUIC/UDP;部分网络对 UDP 限速或封锁。
5.4 TCP 与 QUIC 队头阻塞对比
QUIC 一条连接
流1 丢包
仅流1 重传
流2 正常
流3 正常
TCP 一条连接
流1 丢包
整连接等待重传
流2 被阻塞
流3 被阻塞
六、发展总结表
| 版本 | 发布年份 | 传输层 | 主要改进 | 存在问题 |
|---|---|---|---|---|
| HTTP/1.0 | 1996 | TCP | 首份标准、基本方法/状态码 | 短连接、性能差 |
| HTTP/1.1 | 1997 | TCP | Keep-Alive、管道化、Host、分块 | 队头阻塞、连接数限制 |
| HTTP/2 | 2015 | TCP | 二进制分帧、多路复用、推送、HPACK | TCP 队头阻塞 |
| HTTP/3 | 2022 | QUIC(UDP) | 无队头阻塞、0-RTT、连接迁移 | 部署与 UDP 支持 |
连接与队头阻塞对比图
HTTP/3 单连接多流
同一 QUIC 连接
流1 流2 流3 流4 ...
丢包仅影响对应流
HTTP/2 单连接多流
同一 TCP 连接
流1 流2 流3 流4 ...
HTTP/1.x 多连接
连接1: 请求A → 响应A
连接2: 请求B → 响应B
连接3: 请求C → 响应C
七、未来趋势
- HTTP/3 普及:CDN 与主流云厂商逐步支持,占比持续上升。
- QUIC 演进:IETF 继续扩展 QUIC(如 QPACK、重试与连接迁移细节)。
- 与 HTTP/2 长期共存:因部署与兼容成本,HTTP/2 仍会长期存在。
八、HTTP 版本与核心 RFC 对照表
| 版本 | 年份 | 传输层 | 主要改进概要 | 核心 RFC |
|---|---|---|---|---|
| HTTP/1.0 | 1996 | TCP | 首份标准、短连接 | RFC 1945 |
| HTTP/1.1 | 1997/1999/2014 | TCP | Keep-Alive、Host、分块、缓存等 | RFC 2068/2616;RFC 7230--7235 |
| HTTP/2 | 2015 | TCP | 分帧、多路复用、推送、HPACK | RFC 7540、RFC 7541 |
| HTTP/3 | 2022 | QUIC/UDP | 无 TCP 队头阻塞、0-RTT、迁移 | RFC 9114、RFC 9000;语义 RFC 9110--9113 |
九、核心 RFC 文档详解
9.1 HTTP/1.0 --- RFC 1945 (1996)
定位
第一个正式 HTTP 标准,定义请求/响应、方法、状态码与基本首部,为后续版本奠基。
消息格式
请求(Request):
http
请求行:Method SP Request-URI SP HTTP-Version CRLF
首部: Field-Name ":" OWS Field-Value OWS CRLF (可多行)
空行: CRLF
可选实体:Body
响应(Response):
http
状态行:HTTP-Version SP Status-Code SP Reason-Phrase CRLF
首部: 同上
空行: CRLF
可选实体:Body
示例:
http
GET /index.html HTTP/1.0
Host: (HTTP/1.0 未要求,但部分实现已支持)
HTTP/1.0 200 OK
Content-Type: text/html
Content-Length: 1234
Server: CERN/3.0
<!DOCTYPE html>...
RFC 1945 要点表
| 主题 | 内容 |
|---|---|
| 方法 | GET(取资源)、HEAD(仅取首部)、POST(提交数据) |
| 状态码 | 2xx 成功、3xx 重定向、4xx 客户端错误、5xx 服务端错误;文档中给出 200、201、202、204、301、302、304、400、401、403、404、500 等 |
| 首部 | 通用:Date、Pragma;请求:Authorization、From、If-Modified-Since、Referer、User-Agent 等;响应:Location、Server、WWW-Authenticate、Content-Type、Content-Length、Last-Modified、Expires 等 |
| 连接 | 默认请求完成后关闭连接;无 Keep-Alive 标准化 |
| 局限 | 无 Host,难以虚拟主机;无压缩;性能受短连接限制 |
9.2 HTTP/1.1 --- RFC 7230--7235 (2014)
定位
HTTP/1.1 的现代模块化定义:语法与路由、语义、条件请求、范围请求、缓存、认证分拆到不同 RFC,便于实现与引用。
RFC 7230 --- 消息语法与路由
- 消息结构:起始行(请求行或状态行)+ 头区(Header Section)+ 空行 + 可选消息体。
- 持久连接 :默认
Connection: keep-alive语义,单 TCP 连接上可多发请求/响应;通过Connection: close或响应后关闭。 - 管线化(Pipelining):客户端可连续发多个请求而不等响应;服务器必须按请求顺序回响应。实践中易受代理与实现问题影响,使用较少。
- 分块传输 :
Transfer-Encoding: chunked时,实体按块发送,每块前有十六进制长度 + CRLF,最后一块为0+ CRLF。用于动态生成、流式响应。
分块编码示例:
http
HTTP/1.1 200 OK
Transfer-Encoding: chunked
4\r\n
Wiki\r\n
5\r\n
pedia\r\n
0\r\n
\r\n
RFC 7231 --- 语义与内容
- 方法:GET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE;各自幂等性、安全性、缓存性在 RFC 中定义。
HTTP/1.1 方法速查表:
| 方法 | 幂等 | 安全 | 常见用途 |
|---|---|---|---|
| GET | 是 | 是 | 获取资源表示 |
| HEAD | 是 | 是 | 仅取首部(如探活) |
| POST | 否 | 否 | 提交数据、创建资源 |
| PUT | 是 | 否 | 替换目标资源 |
| DELETE | 是 | 否 | 删除资源 |
| CONNECT | 否 | 否 | 建立隧道(如 HTTPS 代理) |
| OPTIONS | 是 | 是 | 询问支持的方法/能力 |
| TRACE | 是 | 是 | 回显请求(诊断用) |
- 内容协商:Accept、Accept-Language、Accept-Encoding、Accept-Charset 等;服务器据此选表示(Representation)。
- 状态码:按 1xx/2xx/3xx/4xx/5xx 分类,并规定适用场景与首部(如 201 配 Location,206 配 Content-Range)。
RFC 7232 --- 条件请求
- 首部:If-Match、If-None-Match(ETag)、If-Modified-Since、If-Unmodified-Since、If-Range。
- 用途:缓存验证(304 Not Modified)、乐观锁(412 Precondition Failed)、断点续传(If-Range + Range)。
RFC 7233 --- 范围请求
- 请求 :
Range: bytes=0-499等;可多段bytes=0-499,1000-1499。 - 响应 :
Content-Range: bytes 0-499/1234;状态码 206 Partial Content;多段时multipart/byteranges。
RFC 7234 --- 缓存
- 关键首部:Cache-Control(max-age、no-cache、no-store、private、public 等)、Expires、ETag、Last-Modified、Vary。
- 模型:新鲜度(年龄 + max-age/Expires)、验证(条件请求 + 304)、无效化(通过 URL 或缓存键)。
| 指令/首部 | 含义概要 |
|---|---|
| max-age | 响应可被缓存的最大秒数 |
| no-cache | 使用前必须向源站再验证 |
| no-store | 不得存储请求/响应 |
| ETag | 资源版本标识,用于 If-None-Match |
| Last-Modified | 用于 If-Modified-Since |
RFC 7235 --- 认证
- 首部:WWW-Authenticate(质询)、Authorization(凭据)、Proxy-Authenticate、Proxy-Authorization。
- 方案:Basic(Base64 编码)、Digest(摘要认证,防重放)。
9.3 HTTP/2 --- RFC 7540 & RFC 7541
定位
在保持 HTTP 语义的前提下,通过二进制分帧与多路复用提升性能;头部通过 HPACK 压缩,避免 CRIME 类攻击。
RFC 7540 --- HTTP/2 协议
帧通用格式(9 字节头 + 变长 payload):
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
- Length:24 位,payload 长度(不含 9 字节头)。
- Type:帧类型(DATA、HEADERS、SETTINGS 等)。
- Flags:如 END_STREAM、END_HEADERS、PRIORITY 等。
- R :保留位;Stream Identifier:31 位流 ID;0 保留给连接级帧(如 SETTINGS、PING、GOAWAY)。
流状态机(简化):
HEADERS
END_STREAM
END_STREAM
END_STREAM
END_STREAM
RST_STREAM
idle
open
half_closed_remote
half_closed_local
closed
优先级:通过 PRIORITY 或 HEADERS 中的优先级信息,表达流依赖树与权重,用于调度发送顺序。
流量控制:基于 WINDOW_UPDATE 的滑动窗口,可针对单流或整连接;接收方通过窗口控制发送方速率。
RFC 7541 --- HPACK
- 目标:在 HTTP/2 上压缩头部,且不允许通过压缩侧信道推断明文(避免 CRIME)。
- 静态表:预定义约 61 项常用首部(如 :method GET、:status 200、content-type 等),用索引即可表示。
- 动态表:连接生命周期内,将已发送的首部键值对加入表,后续可仅发索引;表大小由 SETTINGS 与 SETTINGS 确认控制。
- 编码:索引(直接引用表项)、字面量(带/不带索引的增量或非增量),配合 Huffman 编码减小长度。
| 编码类型 | 说明 |
|---|---|
| 索引(静态/动态) | 1 字节或更多,指向已存在表项 |
| 字面量增量 | 新键值加入动态表,后续可引用 |
| 字面量非增量 | 仅本次使用,不加入动态表(如敏感头) |
9.4 HTTP/3 --- RFC 9114 & RFC 9000
定位
HTTP 语义跑在 QUIC 之上:传输层改用 QUIC(UDP),消除 TCP 队头阻塞,并利用 QUIC 的 0-RTT、连接迁移与内置 TLS 1.3。
RFC 9000 --- QUIC 传输层
- 承载:UDP;单 UDP 端口上可多路复用多个 QUIC 连接。
- 连接标识:Connection ID,可在 IP/端口变化时保持逻辑连接(连接迁移)。
- 流:双向流与单向流;流内有序,流间独立;丢包只触发该流重传,不阻塞其他流。
- 加密 :默认 TLS 1.3;握手与连接建立合并,支持 1-RTT 首包即可发应用数据;0-RTT 在重连时可在首包带数据(有重放风险,需应用层配合)。
- 帧类型:STREAM、ACK、CRYPTO、CONNECTION_CLOSE、MAX_DATA、MAX_STREAMS 等,用于数据、确认、流控、连接管理。
QUIC 与 TCP 对比(概要):
| 特性 | TCP | QUIC |
|---|---|---|
| 队头阻塞 | 连接内全局 | 仅影响单流 |
| 加密 | 可选(TLS) | 内建 TLS 1.3 |
| 连接建立 | 三次握手 | 1-RTT / 0-RTT |
| 连接迁移 | 一般需重连 | 支持(Connection ID) |
| 拥塞控制 | 内核实现 | 用户空间可扩展 |
RFC 9114 --- HTTP/3
- 映射:HTTP 请求/响应映射到 QUIC 流;通常一请求一流,双向流上先发请求再发响应。
- 帧:在 QUIC STREAM 上承载;帧类型包括 DATA、HEADERS、CANCEL_PUSH、SETTINGS、PUSH_PROMISE、GOAWAY、MAX_PUSH_ID 等;与 HTTP/2 概念对应,但适配 QUIC(无独立 WINDOW_UPDATE,依赖 QUIC 流控)。
- QPACK:头部压缩类似 HPACK,但考虑 QUIC 流乱序,引入编码/解码流与参考集,保证在乱序与丢包下仍可正确解码。
RFC 9110 / 9111 / 9112 / 9113
- RFC 9110:HTTP 语义(方法、状态码、首部含义)的通用定义,适用于 HTTP/1.1、HTTP/2、HTTP/3。
- RFC 9111:缓存语义,与版本解耦。
- RFC 9112:HTTP/1.1 消息格式与语法(与 7230 等对齐的更新版)。
- RFC 9113:HTTP/2 协议(与 7540 对齐的更新版,纳入 911x 系列)。
十、总结
- HTTP/1.0、HTTP/1.1:文本协议、基于 TCP,性能受短连接与队头阻塞限制;1.1 通过持久连接、Host、分块、缓存、条件请求等大幅改善。
- HTTP/2:二进制分帧与多路复用解决应用层队头阻塞,HPACK 压缩头部;仍受 TCP 传输层队头阻塞影响。
- HTTP/3:基于 QUIC(UDP),在传输层消除队头阻塞,并带来 0-RTT、连接迁移与强制加密。
- RFC 体系:从 1.1 的 7230--7235 模块化,到 9110--9113 的跨版本统一语义,形成可扩展、可复用的标准体系。