HTTP 协议:前后端的"通信语言"
🎯 核心问题
HTTP 是如何工作的? 这就像问:两个人如何对话?需要约定语言、语法、对话规则。HTTP 就是前后端之间的"对话协议"。
0. HTTP 的本质
HTTP(HyperText Transfer Protocol,超文本传输协议)是前后端通信的基础协议。
0.1 用对话来类比
| 对话要素 | HTTP 对应 | 说明 |
|---|---|---|
| 语言 | HTTP 协议 | 双方都能理解的语言 |
| 语法 | 请求/响应格式 | 怎么"说话" |
| 流程 | 请求-响应模式 | 一问一答 |
| 结束 | 挂断 | TCP 连接关闭 |
1. HTTP 的发展历程
HTTP 从 1991 年诞生至今,经历了多次重大升级。
HTTP 协议演示
HTTP 请求
GET/api/users/123HTTP/1.1
Host:api.example.com
User-Agent:Mozilla/5.0
Accept:application/json
Authorization:Bearer xxx
TCP 连接
HTTP 响应
HTTP/1.1200OK
Content-Type:application/json
Content-Length:156
Cache-Control:max-age=3600
{
"id": 123,
"name": "张三",
"email": "zhangsan@example.com"
}
1.1 版本对比
| 版本 | 年份 | 核心改进 | 典型特征 |
|---|---|---|---|
| HTTP/0.9 | 1991 | 仅支持 GET | 纯文本,只有请求,无响应头 |
| HTTP/1.0 | 1996 | 增加 POST/HEAD | 每个请求一个 TCP 连接 |
| HTTP/1.1 | 1997 | 持久连接 | Keep-Alive,一个连接多个请求 |
| HTTP/2 | 2015 | 多路复用 | 二进制帧,头部压缩 |
| HTTP/3 | 2022 | 基于 QUIC | UDP 传输,解决队头阻塞 |
💡 为什么需要 HTTP/2?
HTTP/1.1 虽然支持持久连接,但请求必须串行发送(前一个请求的响应返回后,才能发送下一个请求)。HTTP/2 通过多路复用解决了这个问题,可以同时发送多个请求。
2. HTTP 请求的结构
2.1 请求行
http
GET /api/users/123 HTTP/1.1包含三个部分:
- 方法:GET、POST、PUT、DELETE 等
- URL:请求的资源路径
- 版本:HTTP/1.1 或 HTTP/2
2.2 请求头
http
Host: api.example.com
User-Agent: Mozilla/5.0
Accept: application/json
Authorization: Bearer xxx
Content-Type: application/json
Content-Length: 45常见请求头:
| 头部 | 说明 | 示例 |
|---|---|---|
| Host | 服务器域名 | api.example.com |
| User-Agent | 客户端信息 | Mozilla/5.0 |
| Accept | 接受的响应类型 | application/json |
| Authorization | 认证信息 | Bearer token |
| Content-Type | 请求体类型 | application/json |
2.3 请求体
json
{
"name": "张三",
"email": "zhangsan@example.com"
}只有 POST、PUT、PATCH 等方法才有请求体。
3. HTTP 响应的结构
3.1 状态行
http
HTTP/1.1 200 OK包含三个部分:
- 版本:HTTP/1.1
- 状态码:200、404、500 等
- 状态文本:OK、Not Found 等
3.2 响应头
http
Content-Type: application/json
Content-Length: 156
Cache-Control: max-age=3600
Set-Cookie: session=xxx; HttpOnly常见响应头:
| 头部 | 说明 | 示例 |
|---|---|---|
| Content-Type | 响应体类型 | application/json |
| Content-Length | 响应体大小 | 156 |
| Cache-Control | 缓存策略 | max-age=3600 |
| Set-Cookie | 设置 Cookie | session=xxx |
3.3 响应体
json
{
"code": 0,
"data": {
"id": 123,
"name": "张三"
}
}4. HTTP 方法详解
| 方法 | 用途 | 请求体 | 幂等性 | 安全性 |
|---|---|---|---|---|
| GET | 获取资源 | 无 | 是 | 是 |
| POST | 创建资源 | 有 | 否 | 否 |
| PUT | 全量更新 | 有 | 是 | 否 |
| PATCH | 部分更新 | 有 | 否 | 否 |
| DELETE | 删除资源 | 无 | 是 | 否 |
| HEAD | 获取头部 | 无 | 是 | 是 |
| OPTIONS | 查询支持的方法 | 无 | 是 | 是 |
4.1 GET vs POST
| 特性 | GET | POST |
|---|---|---|
| 参数位置 | URL 查询参数 | 请求体 |
| 缓存 | 可缓存 | 默认不缓存 |
| 书签 | 可添加为书签 | 不可 |
| 历史记录 | 保存在浏览器历史 | 不保存 |
| 数据长度 | 有限制(URL 长度) | 无限制 |
| 安全性 | 参数可见在 URL | 参数在请求体中 |
💡 何时使用 GET/POST?
- GET:查询、获取数据
- POST:创建、提交数据
- PUT:全量更新(替换整个资源)
- PATCH:部分更新(只修改指定字段)
- DELETE:删除资源
5. HTTP 状态码
5.1 状态码分类
| 分类 | 说明 | 典型状态码 |
|---|---|---|
| 2xx | 成功 | 200 OK、201 Created、204 No Content |
| 3xx | 重定向 | 301 永久、302 临时、304 未修改 |
| 4xx | 客户端错误 | 400 参数错误、401 未认证、404 不存在 |
| 5xx | 服务端错误 | 500 内部错误、503 不可用 |
5.2 常用状态码
| 状态码 | 说明 | 使用场景 |
|---|---|---|
| 200 OK | 请求成功 | GET、PUT 请求成功 |
| 201 Created | 创建成功 | POST 创建资源成功 |
| 204 No Content | 无内容 | DELETE 删除成功 |
| 301 Moved Permanently | 永久重定向 | URL 永久变更 |
| 302 Found | 临时重定向 | URL 临时变更 |
| 304 Not Modified | 未修改 | 缓存有效 |
| 400 Bad Request | 参数错误 | 请求参数格式错误 |
| 401 Unauthorized | 未认证 | 需要登录 |
| 403 Forbidden | 无权限 | 已登录但权限不足 |
| 404 Not Found | 不存在 | 资源不存在 |
| 500 Internal Server Error | 内部错误 | 服务器异常 |
| 503 Service Unavailable | 不可用 | 服务器维护或过载 |
6. HTTPS:安全的 HTTP
6.1 HTTP vs HTTPS
| 特性 | HTTP | HTTPS |
|---|---|---|
| 协议 | TCP | TCP + SSL/TLS |
| 端口 | 80 | 443 |
| 数据 | 明文传输 | 加密传输 |
| 证书 | 不需要 | 需要 SSL 证书 |
| 性能 | 略快 | 略慢(握手开销) |
| SEO | 无影响 | 搜索引擎优先收录 |
6.2 HTTPS 的工作流程
- Client Hello:客户端发送支持的加密套件
- Server Hello:服务器返回证书和选定的加密套件
- 验证证书:客户端验证服务器证书的有效性
- 密钥交换:使用非对称加密交换会话密钥
- 加密通信:使用会话密钥进行对称加密通信
💡 HTTPS 的优势
- 防窃听:数据加密,第三方无法读取
- 防篡改:数据完整性校验
- 防冒充:SSL 证书验证服务器身份
7. HTTP 缓存机制
7.1 缓存头
| 头部 | 说明 | 示例 |
|---|---|---|
| Cache-Control | 缓存策略 | max-age=3600 |
| ETag | 资源版本号 | "33a64df551425fcc" |
| Last-Modified | 最后修改时间 | Wed, 21 Oct 2015 07:28:00 GMT |
7.2 缓存策略
强缓存:
http
Cache-Control: max-age=3600在 3600 秒内,浏览器直接使用缓存,不发送请求。
协商缓存:
http
ETag: "33a64df551425fcc"浏览器发送 If-None-Match,服务器返回 304(未修改)或 200(已修改)。
8. 常见问题
8.1 GET 和 POST 的本质区别
误区:GET 和 POST 的区别只是参数位置不同。
真相:
- GET 是幂等的,多次请求结果相同
- POST 是非幂等的,多次请求可能创建多个资源
- GET 可被缓存,POST 默认不缓存
- GET 可被书签保存,POST 不可
8.2 HTTP/1.1 的队头阻塞
问题:HTTP/1.1 虽然支持持久连接,但请求必须串行发送。前一个请求响应慢,后续请求都要等待。
解决方案:
- HTTP/2 多路复用
- 域名分片(多个域名建立多个连接)
- 连接池(限制并发数)
8.3 HTTP/2 的优势
| 特性 | HTTP/1.1 | HTTP/2 |
|---|---|---|
| 传输格式 | 文本 | 二进制帧 |
| 多路复用 | 不支持 | 支持 |
| 头部压缩 | 无 | HPACK 算法 |
| 服务器推送 | 不支持 | 支持 |
名词速查表
| 名词 | 英文 | 解释 |
|---|---|---|
| HTTP | HyperText Transfer Protocol | 超文本传输协议 |
| HTTPS | HTTP Secure | HTTP + SSL/TLS |
| TCP | Transmission Control Protocol | 传输控制协议 |
| SSL/TLS | Secure Sockets Layer | 安全套接层 |
| 幂等性 | Idempotent | 多次请求结果相同 |
| 持久连接 | Keep-Alive | 一个 TCP 连接发送多个请求 |
| 多路复用 | Multiplexing | 同时发送多个请求 |
| 队头阻塞 | Head-of-Line Blocking | 前面的请求阻塞后面的请求 |
