注:本文基于模型知识整理,建议结合权威教材与 RFC 原文核对细节。
一句话定义
HTTP(HyperText Transfer Protocol,超文本传输协议)是构建在 TCP 之上的请求-响应式应用层协议,规定了客户端与服务器之间报文的格式、方法的语义与状态码体系,是 Web 与绝大多数 API 通信的地基。
为什么重要
浏览器打开网页、App 调后端接口、微服务互调、爬虫抓取,底层几乎都是 HTTP。读懂方法与状态码是排障基本功:502 与 503 指向完全不同的故障层,301 与 302 影响搜索引擎收录与浏览器缓存行为。同时,HTTP 的无状态设计是理解会话管理(Cookie/Token)、负载均衡与 Web 缓存(kp-027)的前提,也是从 HTTP/1.1 演化到 HTTP/2 的出发点。
前置知识
建议先读 kp-017《UDP》,掌握传输层端口与无连接/面向连接的语义;HTTP/1.1 实际跑在 TCP 上,三次握手与字节流细节见 kp-018《TCP 连接管理》。
核心概念
- 请求-响应与无状态:严格的一问一答,服务器默认不记得上一个请求来自谁。无状态(stateless)是双刃剑:任意后端节点都能处理任意请求,利于横向扩展与缓存;代价是登录态等跨请求信息必须由 Cookie 等机制在客户端「补」回来。
- 报文结构:请求报文由请求行(方法、路径、版本)、若干首部字段(键不区分大小写的键值对)、一个空行(CRLF)与可选消息体组成;响应报文对应为状态行(版本、状态码、原因短语)加首部、空行与消息体。
- 方法语义:GET(读取)、HEAD(同 GET 但只要首部)、POST(提交处理)、PUT(整体替换目标资源)、DELETE(删除)、OPTIONS(询问支持的方法,CORS 预检使用)。两个关键属性:安全(safe)指不改变服务器状态;幂等(idempotent)指执行一次与多次效果相同。GET 幂等且安全;PUT 幂等但不安全;POST 两者皆非。
- 状态码五大类:1xx 信息性、2xx 成功、3xx 重定向、4xx 客户端错误、5xx 服务器错误。必会值:200 成功;301 永久重定向与 302 临时重定向(301 提示客户端与搜索引擎更新地址,302 不更新);304 Not Modified(协商缓存命中,见 kp-027);400 请求语法错误;401 未认证与 403 禁止(401 是「不知道你是谁」,403 是「知道你是谁但没权限」);404 资源不存在;429 请求过多(限流);500 服务器内部错误;502 网关从上游收到无效响应与 503 服务过载或维护。
- Cookie 机制:服务器用 Set-Cookie 下发,浏览器之后对匹配的请求自动携带。关键属性:Domain/Path 决定作用域;Expires/Max-Age 决定有效期(缺省为会话 Cookie,关浏览器即失效);HttpOnly 阻止 JavaScript 读取(缓解 XSS 窃取会话);Secure 限定仅经 HTTPS 传输;SameSite 限制跨站请求是否携带(Strict/Lax/None),用于缓解 CSRF。
- 从 1.0 到 1.1 的关键改进:新增 Host 首部,一台服务器一个 IP 可按域名托管多个站点(虚拟主机);默认持久连接 keep-alive,一条 TCP 连接服务多个请求,省去每个请求的三次握手;管线化(pipelining)允许不等响应就连发多个请求,但响应必须严格按发出顺序返回,慢请求会堵住后面所有响应——这就是队头阻塞(head-of-line blocking),浏览器因兼容性与阻塞问题基本弃用,为 HTTP/2 的分帧多路复用埋下伏笔。
图示
请求与响应报文的结构对照:
请求报文(客户端 → 服务器) 响应报文(服务器 → 客户端)
请求行: GET /api/users/1 HTTP/1.1 状态行: HTTP/1.1 200 OK
首部: Host: api.example.com 首部: Content-Type: application/json
Accept: application/json Content-Length: 11
空行: (仅 CRLF,标志首部结束) 空行: (仅 CRLF)
消息体: (GET 通常没有) 消息体: <h1>hi</h1>原理与机制
无状态如何补状态。 服务器不保存跨请求的会话上下文,会话标识被下放到客户端:登录成功后服务器 Set-Cookie 一个会话 ID,浏览器后续每个请求自动携带,服务器据此查会话存储识别用户。正因状态外置,后端可以无差别扩容,负载均衡不强依赖会话粘滞。
持久连接与队头阻塞。 1.0 每个请求都要新建 TCP 连接,反复付出三次握手与慢启动代价;1.1 默认 keep-alive 复用连接。但复用是「串行等响应」:一条连接同一时刻只有一个未完成响应,其余请求只能排队。浏览器的粗暴解法是对同一域名并发开 6 条连接;管线化看似允许多请求同时在途,但「响应必须按序返回」的规则只是把队头搬进了管道,根本问题没有消除——出路是改变报文的组织方式,这引出了 kp-025 的二进制分帧。
实例分析
完整交互(可用 curl -v 或 telnet 复现):
GET /api/users/1 HTTP/1.1
Host: api.example.com
Cookie: session=abc123
Accept: application/json
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"
Content-Length: 0解读:请求带了会话 Cookie 但凭证已过期,服务器返回 401 要求重新认证——不是 403,因为服务器此刻还不确认「你是谁」,谈不上拒绝授权。再看网关层:后端进程崩溃时网关收到无效上游响应,返回 502;后端过载保护主动拒绝时返回 503。运维据此分流排查方向。
常见误区
- 401 与 403 混用:权限不足误回 401,会误导客户端反复走登录流程;正确语义是 403。
- 幂等不等于安全:DELETE 幂等(重复删除效果一致)但显然改变状态,不安全。
- 301 与 302 混用:临时迁移误用 301,浏览器与搜索引擎会长期缓存新地址,回滚困难。
- 把 GET 当写接口、在 GET 里塞消息体:违反语义且部分代理/缓存会出问题;写操作用 POST/PUT。
- 认为 Cookie 是唯一会话方案:Token 方案只是把凭证从 Cookie 挪到 Authorization 头,「无状态」的设计没有变。
自测题
- GET、PUT、POST 各自的安全性(safe)与幂等性(idempotent)如何?
答案要点: GET 安全且幂等;PUT 幂等但不安全(重复替换结果一致,但改变了状态);POST 既不安全也不幂等(每次提交可能产生新副作用)。
- 401 与 403 的语义区别是什么?
答案要点: 401 表示未认证,需要提供有效凭证(常伴随 WWW-Authenticate 头);403 表示服务器已知身份但拒绝授权,再认证也不会改变结果。
- HTTP/1.1 的管线化为什么失败,它暴露的根本问题叫什么?
答案要点: 管线化要求响应严格按请求顺序返回,慢响应阻塞后续所有响应,浏览器因兼容与阻塞弃用了它;根本问题是应用层队头阻塞,后来由 HTTP/2 的二进制分帧与多路复用在应用层解决。
- SameSite 属性防的是什么攻击?HttpOnly 防的是什么?
答案要点: SameSite 限制 Cookie 随跨站请求自动携带,缓解 CSRF;HttpOnly 禁止 JavaScript 读取 Cookie,缓解 XSS 窃取会话凭证。
- 502 与 503 分别提示什么故障?
答案要点: 502 说明作为网关/代理的这一层从上游收到了无效响应或连接失败,问题通常在上游服务;503 说明服务本身过载或维护中,问题在当前服务的容量与可用性。
延伸阅读
- 《HTTP 权威指南》(O'Reilly)
- 《图解 HTTP》(上野宣)
- RFC 9110(语义)、RFC 9112(HTTP/1.1 报文与连接)、RFC 6265(Cookie)