HTTP语义方法

HTTP 方法语义:GET/POST/PUT/PATCH/DELETE 的安全性、幂等性与常见误区。

#type / concept #status / growing #resource / http #tech / network #protocol / http

[!info] related notes

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 次,服务器上的数据状态都不会发生改变,仅仅是“读”而已。

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)。
  • 幂等性: 它是幂等的。你把“张三的年龄改成 20”这个完整覆盖的动作执行 1 次和 100 次,最终结果都是一样的。

4. PATCH:改 (Update - 局部修改) - “打个补丁”

  • 语义: 对资源进行部分修改
  • 举例: 同样是修改年龄。
    • 使用 PATCH 时,你只需要传你要改的那个字段:{"age": 20}。服务器只会更新这一个字段,其他字段保持原样。
  • 对比: 相比 PUT,PATCH 更节省网络带宽,也更符合现代前端按需提交表单的逻辑。在实际业务中,PATCH 比 PUT 更好用、更主流。

5. DELETE:删 (Delete) - “把它删了”

  • 语义: 请求服务器删除指定的资源。
  • 特征: 和 GET 类似,通常不需要请求体,目标资源的 ID 会直接体现在 URL 中(比如 DELETE /api/users/123)。它也是幂等的(删一次和删多次,最终该资源都不存在了)。

💡 核心概念:什么是“幂等性 (Idempotency)”?

在面试或高级架构设计中,幂等性是一个必考题。

简单来说:一个操作执行一次和执行多次,对系统状态产生的影响是一样的。

方法数据库操作对应是否安全(不改数据)是否幂等(多次执行结果相同)
GETRead (查)✅ 是✅ 是
POSTCreate (增)❌ 否❌ 否 (可能会创建多个)
PUTUpdate (全量改)❌ 否✅ 是 (直接覆盖,结果唯一)
PATCHUpdate (局部改)❌ 否⚠️ 大多数情况下是 (取决于具体实现)
DELETEDelete (删)❌ 否✅ 是 (不管删多少次,东西都没了)

为什么幂等性很重要?

因为网络是不可靠的。假设前端发了一个请求,因为网络卡顿没有收到后端的响应,前端(或者浏览器、网关)可能会自动重试。如果接口不是幂等的(比如转账 POST 接口),自动重试就会导致用户被扣两次钱。如果是幂等的(比如 GET 获取余额),重试多少次都没关系。

创建于 2026/3/12 更新于 2026/5/27