反馈

HTTP 协议基础:请求响应结构、方法、状态码和版本演进

HTTP(HyperText Transfer Protocol,超文本传输协议)是整个万维网运转的基础协议,浏览器打开一个网页、App 请求一个接口,底层几乎都是一次或多次 HTTP 请求/响应。本文把请求响应结构、常见方法、状态码和版本演进讲清楚。


目录

  1. 请求和响应的报文结构
  2. 常见方法和幂等性
  3. 状态码怎么分类
  4. HTTP/1.1 到 HTTP/3:每一代解决了什么问题
  5. 无状态协议:Cookie 和 Session 为什么存在

1. 请求和响应的报文结构

HTTP 报文分请求和响应两种,结构都是"起始行 + Header + 空行 + Body":

请求:
GET /api/users?id=1 HTTP/1.1        ← 请求行:方法 路径 版本
Host: example.com                    ← Header
User-Agent: Mozilla/5.0
                                      ← 空行,分隔 Header 和 Body
(GET 通常没有 Body)

响应:
HTTP/1.1 200 OK                      ← 状态行:版本 状态码 状态描述
Content-Type: application/json       ← Header
Content-Length: 27

{"id":1,"name":"Alice"}              ← Body

Header 是键值对,携带元信息(内容类型、长度、认证、缓存策略等),Body 是实际传输的数据本体。

2. 常见方法和幂等性

方法 用途 是否幂等
GET 获取资源 是——多次请求结果一样,不改变服务器状态
POST 创建资源/提交数据 否——多次请求可能创建多条记录
PUT 整体替换资源 是——用同样的数据多次 PUT,结果和只 PUT 一次一样
PATCH 部分修改资源 否(严格来说不保证,取决于实现)
DELETE 删除资源 是——删除一个已经不存在的资源,结果和删除前一样(都是"不存在")

幂等(Idempotent) 指的是"同一个请求重复执行多次,效果和执行一次相同"。这个性质很实际:网络不稳定导致请求超时后,客户端能不能安全地自动重试,取决于这个方法是不是幂等的——GET/PUT/DELETE 可以放心重试,POST 重试可能导致重复下单之类的问题。

3. 状态码怎么分类

状态码是三位数字,首位数字决定了大类:

分类 含义 常见状态码
1xx 信息性,协议处理中间状态 101 切换协议(WebSocket 握手用)
2xx 成功 200 OK、201 已创建、204 无内容
3xx 重定向 301 永久重定向、302 临时重定向、304 未修改(配合缓存)
4xx 客户端错误 400 请求有误、401 未认证、403 无权限、404 未找到、429 请求过多
5xx 服务器错误 500 服务器内部错误、502 网关错误、503 服务不可用

一个容易混淆的点:401 和 403 都表示"不让你访问",但含义不同——401 是"你没证明自己是谁"(缺少或无效的身份凭证,通常要求重新登录),403 是"我知道你是谁,但你没有权限做这件事"(身份没问题,但操作被拒绝)。

4. HTTP/1.1 到 HTTP/3:每一代解决了什么问题

  • HTTP/1.1(1997):引入持久连接(Keep-Alive),不用每个请求都重新建立 TCP 连接,但同一条连接上的多个请求必须按顺序处理完——如果前一个请求慢,后面的请求即使已经准备好响应也要排队等,这就是"队头阻塞(Head-of-Line Blocking)"
  • HTTP/2(2015):引入多路复用,同一条 TCP 连接上可以同时并行处理多个请求响应,不再互相阻塞;同时用二进制分帧代替文本格式、用 HPACK 压缩 Header,减少重复传输的开销。但 HTTP/2 仍然跑在 TCP 上,如果 TCP 层出现丢包重传,同一条连接上的所有 HTTP/2 流都会被拖慢——队头阻塞问题从"应用层"下沉到了"传输层"
  • HTTP/3(2022 正式标准化):改用基于 UDP 的 QUIC 协议替代 TCP 作为传输层,每个 HTTP/3 流有独立的丢包重传机制,一个流的丢包不会拖累其它流,从根本上解决了队头阻塞;同时 QUIC 内置了类似 TLS 的加密和更快的连接建立(0-RTT/1-RTT)

5. 无状态协议:Cookie 和 Session 为什么存在

HTTP 本身是无状态的——服务器处理完一个请求就"忘了"这次交互,下一个请求即使来自同一个用户,服务器默认也不知道"这是刚才那个人"。但网站需要记住"你是否登录""购物车里有什么",解决方法是让客户端在每次请求里主动带上标识信息:服务器在响应里用 Set-Cookie 下发一个标识(比如 Session ID),浏览器后续每次请求自动带上这个 Cookie,服务器就能把多次独立的请求"串联"成同一个用户的会话——无状态的协议之上,靠 Cookie/Session 实现了有状态的用户体验。


在线工具:Http接口测试