HTTP语义方法
HTTP 方法语义:GET/POST/PUT/PATCH/DELETE 的安全性、幂等性与常见误区。
#type / concept
#status / growing
#resource / http
#tech / network
#protocol / http
[!info] related notes
- 所属 MOC: http-and-frontend-networking-moc
- 语义总览: http
HTTP语义方法
在早期的 Web 开发中,大家通常只用 GET(获取页面)和 POST(提交表单)。但随着 RESTful API 设计风格的流行,HTTP 方法被赋予了更明确的**“语义”**。这就好比把 HTTP 请求变成了一句完整的话:“用什么动作(Method),去操作哪个目标(URL)”。
1. GET:查 (Read) - “给我看看”
- 语义: 向服务器请求获取指定资源。
- 特征:
- 参数位置: 数据通常拼接在 URL 后面(Query String,例如
?id=1&type=vip)。 - 可见性: 参数在浏览器地址栏完全可见,绝对不要用 GET 传递密码等敏感信息。
- 缓存友好: 浏览器会自动缓存 GET 请求(这也就是为什么有时前端代码更新了,用户还要清缓存才能看到)。
- 安全性(幂等性): 它是**幂等(Idempotent)**的。意思是,你请求 1 次和请求 10000 次,服务器上的数据状态都不会发生改变,仅仅是“读”而已。
- 参数位置: 数据通常拼接在 URL 后面(Query String,例如
2. POST:增 (Create) - “新建一个”
- 语义: 向服务器提交数据,通常用于创建新的资源,或者触发某种非幂等的处理逻辑。
- 特征:
- 参数位置: 数据放在请求体(Request Body)中,地址栏不可见。
- 数据类型: 支持多种格式,如 JSON (
application/json)、表单 (application/x-www-form-urlencoded) 或文件上传 (multipart/form-data)。 - 非幂等: 这是 POST 最关键的特征。如果你连续发送两次相同的 POST 请求,服务器可能会创建两个相同的订单或账户。这也是为什么我们在前端经常要做“按钮防抖”,防止用户手抖连点两次导致重复提交。
3. PUT:改 (Update - 全量替换) - “整个换掉”
- 语义: 用请求体中的有效负载(Payload),完整地替换目标资源的所有当前表示。
- 举例: 假设用户资料有
name,age,gender三个字段。你想把年龄改成 20 岁。- 使用 PUT 时,你必须把这三个字段全部传给后端:
{"name": "张三", "age": 20, "gender": "男"}。如果你只传了 age,后端的规范做法是把 name 和 gender 清空(设为 null)。
- 使用 PUT 时,你必须把这三个字段全部传给后端:
- 幂等性: 它是幂等的。你把“张三的年龄改成 20”这个完整覆盖的动作执行 1 次和 100 次,最终结果都是一样的。
4. PATCH:改 (Update - 局部修改) - “打个补丁”
- 语义: 对资源进行部分修改。
- 举例: 同样是修改年龄。
- 使用 PATCH 时,你只需要传你要改的那个字段:
{"age": 20}。服务器只会更新这一个字段,其他字段保持原样。
- 使用 PATCH 时,你只需要传你要改的那个字段:
- 对比: 相比 PUT,PATCH 更节省网络带宽,也更符合现代前端按需提交表单的逻辑。在实际业务中,PATCH 比 PUT 更好用、更主流。
5. DELETE:删 (Delete) - “把它删了”
- 语义: 请求服务器删除指定的资源。
- 特征: 和 GET 类似,通常不需要请求体,目标资源的 ID 会直接体现在 URL 中(比如
DELETE /api/users/123)。它也是幂等的(删一次和删多次,最终该资源都不存在了)。
💡 核心概念:什么是“幂等性 (Idempotency)”?
在面试或高级架构设计中,幂等性是一个必考题。
简单来说:一个操作执行一次和执行多次,对系统状态产生的影响是一样的。
| 方法 | 数据库操作对应 | 是否安全(不改数据) | 是否幂等(多次执行结果相同) |
|---|---|---|---|
| GET | Read (查) | ✅ 是 | ✅ 是 |
| POST | Create (增) | ❌ 否 | ❌ 否 (可能会创建多个) |
| PUT | Update (全量改) | ❌ 否 | ✅ 是 (直接覆盖,结果唯一) |
| PATCH | Update (局部改) | ❌ 否 | ⚠️ 大多数情况下是 (取决于具体实现) |
| DELETE | Delete (删) | ❌ 否 | ✅ 是 (不管删多少次,东西都没了) |
为什么幂等性很重要?
因为网络是不可靠的。假设前端发了一个请求,因为网络卡顿没有收到后端的响应,前端(或者浏览器、网关)可能会自动重试。如果接口不是幂等的(比如转账 POST 接口),自动重试就会导致用户被扣两次钱。如果是幂等的(比如 GET 获取余额),重试多少次都没关系。