一、HTTP 协议概述:从诞生到现代
1.1 HTTP 到底是什么?
HTTP,全称 HyperText Transfer Protocol,超文本传输协议。
说白了,它就是客户端和服务器之间沟通的“共同语言”。你打开浏览器,输入网址,敲回车——浏览器就用 HTTP 把请求发出去。服务器收到后,也用 HTTP 把网页内容返回来。
我刚开始接触 Web 开发时,总觉得 HTTP 就是个“发请求、收响应”的黑盒子。直到有一次线上故障,排查了半天才发现是请求头里少了个 Host 字段。嗯,从那以后我才真正重视起这个协议。
HTTP 有几个核心特点:
- 基于 TCP/IP:底层靠 TCP 保证数据可靠传输
- 无状态:服务器默认不记住你之前的请求
- 明文传输:早期版本数据是明文的,后来 HTTPS 才加密
- 请求-响应模型:客户端主动发,服务器被动回
一句话总结:HTTP 是 Web 世界的“快递员”——你下单(请求),它送货(响应)。
1.2 HTTP 的历史版本演进
HTTP 从诞生到现在,经历了五个主要版本。每个版本都解决了上一代的核心痛点。
| 版本 | 诞生年份 | 核心特点 | 典型问题 |
|---|---|---|---|
| HTTP/0.9 | 1991 | 只有 GET,只返回 HTML | 功能极其有限 |
| HTTP/1.0 | 1996 | 支持多种方法、请求头、响应头 | 每个请求新建 TCP 连接 |
| HTTP/1.1 | 1997 | 持久连接、管道化、分块传输 | 队头阻塞 |
| HTTP/2.0 | 2015 | 二进制分帧、多路复用、头部压缩 | TCP 层面的队头阻塞 |
| HTTP/3.0 | 2022 | 基于 QUIC(UDP),彻底解决队头阻塞 | 部署成本高 |
HTTP/0.9:极简原型
1991 年,Tim Berners-Lee 发布了第一个版本。它简单到什么程度?
- 只有
GET方法 - 没有请求头、响应头
- 只能返回 HTML 文本
- 连接用完即断
举个例子,当时的请求长这样:
GET /index.html
服务器直接返回 HTML 内容,没有状态码,没有 Content-Type。你想想看,连 404 都没有——如果资源不存在,服务器直接返回空。
HTTP/1.0:功能补全
1996 年,HTTP/1.0 正式标准化。它引入了:
- 多种方法:GET、POST、HEAD
- 请求头/响应头:比如
Content-Type、Content-Length - 状态码:200、404、500 等
- 支持非 HTML 资源:图片、样式表、脚本
但有个致命问题——每个请求都要新建一个 TCP 连接。一个网页如果有 10 张图片,就要建立 10 次 TCP 连接。三次握手、慢启动……性能开销非常大。
避坑提醒:我曾经在优化一个老项目时,发现页面加载慢不是因为带宽,而是因为 HTTP/1.0 的短连接导致大量 TCP 握手。换成 HTTP/1.1 后,加载时间直接降了 40%。
HTTP/1.1:持久连接时代
1997 年发布的 HTTP/1.1,至今仍是使用最广泛的版本。它解决了 1.0 的核心痛点:
- 持久连接:默认开启
Connection: keep-alive,多个请求复用同一个 TCP 连接 - 管道化:客户端可以连续发多个请求,不必等前一个响应
- 分块传输编码:服务器可以边生成边发送,不用等全部内容就绪
- Host 头:支持一台服务器托管多个域名
- 更多方法:PUT、DELETE、OPTIONS 等
但管道化有个坑——队头阻塞。什么意思?
假设你发了三个请求:请求 1、请求 2、请求 3。服务器必须按顺序处理,响应也是按顺序返回。如果请求 1 的处理很慢,请求 2 和请求 3 就得干等着。这就是队头阻塞。
我个人习惯在排查性能问题时,第一件事就是看有没有队头阻塞。用 Chrome 开发者工具的 Network 面板,如果看到请求排队时间很长,基本就是它了。
HTTP/2.0:多路复用破局
2015 年,HTTP/2.0 发布。它没有改变 HTTP 的语义——请求方法、状态码、头字段都跟 1.1 一样。但底层传输机制彻底变了:
- 二进制分帧:不再是文本协议,而是二进制格式
- 多路复用:一个 TCP 连接上可以同时传输多个请求和响应
- 头部压缩:用 HPACK 算法压缩重复的头部字段
- 服务器推送:服务器可以主动把资源推给客户端
多路复用解决了 HTTP/1.1 的队头阻塞。请求 1 慢?没关系,请求 2 和请求 3 的响应可以插队先回来。
但 HTTP/2.0 仍然基于 TCP。TCP 本身也有队头阻塞——如果某个 TCP 包丢了,后续所有包都得等重传。这就是所谓的“TCP 层面的队头阻塞”。
HTTP/3.0:QUIC 时代
2022 年,HTTP/3.0 正式标准化。它把底层从 TCP 换成了 QUIC(基于 UDP)。
- 0-RTT 连接:第一次连接后,后续请求可以零往返时间建立连接
- 彻底解决队头阻塞:一个流丢包不影响其他流
- 连接迁移:从 Wi-Fi 切到 4G,连接不会断
我记得有一次帮客户优化海外用户的访问速度。他们用了 HTTP/2.0,但东南亚地区的网络丢包率很高,TCP 重传导致体验很差。换成 HTTP/3.0 后,首屏加载时间从 8 秒降到了 2 秒。
小提示:目前 HTTP/3.0 的普及率还在上升。如果你的用户群体集中在网络环境差的地区,建议优先考虑升级。
1.3 HTTP 的工作模式:请求-响应模型
HTTP 的工作模式非常直观——客户端主动发起请求,服务器被动返回响应。这就是请求-响应模型。
整个过程分四步:
- 建立连接:客户端与服务器建立 TCP 连接(HTTP/3 是 QUIC 连接)
- 发送请求:客户端发送 HTTP 请求报文
- 处理请求:服务器解析请求,执行逻辑,生成响应
- 返回响应:服务器发送 HTTP 响应报文
一个典型的 HTTP 请求报文长这样:
GET /api/users HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Accept: application/json
响应报文长这样:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 123
{"users": [{"id": 1, "name": "Alice"}]}
这里有个关键点——HTTP 是无状态的。服务器不会记住你之前发过什么请求。每次请求都是独立的。
为什么会这样?
因为设计初衷是“简单”。无状态让服务器更容易扩展——你可以在后面挂 100 台服务器,每台都不需要共享会话信息。但这也带来了问题:登录状态怎么保持?购物车怎么记住?
解决方案就是 Cookie 和 Session。客户端在请求头里带上 Cookie,服务器根据 Cookie 找到对应的 Session 数据。嗯,这个我们后面章节会详细讲。
1.4 核心知识体系图
下面这张图展示了本章的核心知识结构:
1.5 本章小结
这一章我们聊了 HTTP 是什么、它经历了哪些版本、以及它的工作模式。核心就三件事:
- HTTP 是 Web 通信的基石,基于 TCP/IP,无状态,请求-响应模型
- 版本演进:0.9(极简)→ 1.0(功能补全)→ 1.1(持久连接)→ 2.0(多路复用)→ 3.0(QUIC)
- 工作模式:客户端发请求,服务器回响应,每次请求独立