返回首页

HTTP发展历程

布莱克2026-06-03 16:27已编辑
Tip:文章封面与内容无关,作者旅游时拍摄,因为没什么值得把四季都错过!

HTTP/1.0(1996)

特性解决的问题
请求方法(GET、POST、HEAD)支持表单提交、获取元信息
状态码(200、404、500 等)客户端能判断请求结果
请求/响应头Content-Type、Content-Length、User-Agent
Cache 机制(Expires、Pragma: no-cache)减少重复请求

❌ 核心问题:短连接

  • 每个请求建立一次 TCP 连接,请求完成后立即断开
  • 一个 HTML 里引用了 10 张图片 → 建立 11 次 TCP 连接
  • 每次 TCP 连接都要三次握手 +(HTTPS 时)TLS 握手
  • 连接数过多时,操作系统文件描述符耗尽

HTTP/1.1(1999)

1. 持久连接(Keep-Alive)

Connection: keep-alive
  • 一个 TCP 连接可以发送多个请求/响应
  • 减少 TCP 握手和 TLS 握手次数
  • 成为默认行为(HTTP/1.1 中默认开启)

2. 管道化(Pipelining)

  • 客户端可以连续发送多个请求,无需等待每个响应返回
  • 但服务器必须按顺序返回响应
  • 实际使用中问题太多(队头阻塞、幂等性要求),浏览器默认关闭

3. Host 头

Host: www.example.com
  • 一台服务器可以托管多个域名(虚拟主机)
  • 这是今天云服务、CDN 的基础

4. 分块传输编码(Chunked Transfer Encoding)

text

Transfer-Encoding: chunked
  • 服务器不知道 Content-Length 时,可以分块发送
  • 流式传输、Server-Sent Events(SSE)的基础

5. 更强的缓存控制

  • Cache-Control(max-age、no-cache、no-store)
  • ETag(实体标签,用于条件请求)
  • If-None-Match、If-Modified-Since

6. 新增请求方法

  • PUT、DELETE、OPTIONS、TRACE、CONNECT


HTTP1.1请求

页面加载 example.com(包含 20 个资源)

浏览器行为:
┌─────────────────────────────────────────────────────────────┐
│  建立 6 个 TCP 连接到 example.com(连接池)                   │
└─────────────────────────────────────────────────────────────┘

连接1(TCP端口 12345): 请求A → 响应A → 请求G → 响应G → 请求M → 响应M
                        └─串行─┘      └─串行─┘      └─串行─┘

连接2(TCP端口 12346): 请求B → 响应B → 请求H → 响应H → 请求N → 响应N
                        └─串行─┘      └─串行─┘      └─串行─┘

连接3(TCP端口 12347): 请求C → 响应C → 请求I → 响应I → 请求O → 响应O
                        └─串行─┘      └─串行─┘      └─串行─┘

连接4(TCP端口 12348): 请求D → 响应D → 请求J → 响应J → 请求P → 响应P
                        └─串行─┘      └─串行─┘      └─串行─┘

连接5(TCP端口 12349): 请求E → 响应E → 请求K → 响应K → 请求Q → 响应Q
                        └─串行─┘      └─串行─┘      └─串行─┘

连接6(TCP端口 12350): 请求F → 响应F → 请求L → 响应L → 请求R → 响应R
                        └─串行─┘      └─串行─┘      └─串行─┘

关键点:
✅ 6个连接之间是并行的(同时工作)
❌ 每个连接内部是串行的(必须等前一个响应回来,才能发下一个请求)


HTTP/2(2015)

1. 二进制分帧层(Binary Framing Layer)

  • 将 HTTP 消息拆分为二进制帧(HEADERS 帧、DATA 帧、SETTINGS 帧等)
  • 帧可以被乱序发送、乱序接收,最后按流 ID 重组
  • 为多路复用奠定基础

2. 多路复用(Multiplexing)

  • 一个 TCP 连接上同时交错发送多个请求和响应
  • 彻底解决了 HTTP/1.1 的应用层队头阻塞
  • 无需域名分片,一个域名一个连接足够

3. 头部压缩(HPACK)

  • 静态字典:预定义 61 个常见头(:method: GET、:path: / 等)
  • 动态字典:通信过程中双方共建的键值对表
  • Huffman 编码:压缩文本
  • 头部体积减少 80%~90%,无安全漏洞(区别于 SPDY 的压缩方案)

4. 服务器推送(Server Push)

  • 请求 HTML 时,服务器可主动推送 CSS、JS
  • 减少往返延迟
  • ⚠️ 但容易过度推送,实际使用中谨慎

HTTP2请求

同一个 TCP 连接(只需要1个):

时间轴 →
请求A(Stream1) ────────────────────── 响应A(Stream1) ─────────>
请求B(Stream2) ──────────── 响应B(Stream2) ──────>
请求C(Stream3) ── 响应C(Stream3) ──>
请求D(Stream4) ───────────────────────────────── 响应D(Stream4) →

所有请求可以同时发送,响应可以乱序返回
因为每个帧都有 Stream ID 来标识属于哪个请求


assistant