HTTP请求方法与幂等性
概念引入
想象飞翔公司的 OA 系统是一个智能文件柜:
- GET = 打开抽屉查看文件(只看不动)
- POST = 往抽屉里塞一份新文件(每次塞都多一份)
- PUT = 把抽屉里的旧文件换成新版本(换几次结果一样)
- DELETE = 把文件抽出来扔掉(抽一次和抽十次,抽屉都是空的)
HTTP 定义了多种请求方法(Method),每种方法代表对服务器资源的"操作意图"。选对方法,就像选对工具——用螺丝刀拧螺丝,用锤子钉钉子,各司其职。
核心内容
HTTP/1.1 标准方法一览
| 方法 | 含义 | 生活比喻 | 飞翔公司场景 |
|---|---|---|---|
| GET | 获取资源 | 到档案室查阅资料 | 空少查看官网首页 |
| POST | 提交数据,创建资源 | 填写入职申请表 | 波比提交活动策划方案 |
| PUT | 更新/替换资源 | 把旧合同换成新合同 | 航仔更新个人技术栈资料 |
| DELETE | 删除资源 | 碎纸机销毁过期文件 | 鸣哥删除未发布的草稿文章 |
| HEAD | 获取资源的元信息(不返回主体) | 只看档案袋封面 | 凌叔检查服务器文件是否存在 |
| OPTIONS | 查询服务器支持的方法 | 问前台"这里能办什么业务" | 翼王检查 API 支持哪些操作 |
| TRACE | 回显服务器收到的请求(调试用) | 录音回放确认对方听到了什么 | 排查代理服务器是否篡改请求 |
| CONNECT | 建立隧道(常用于 HTTPS) | 打通一条专用保密通道 | 浏览器建立 TLS 加密连接 |
GET 与 POST 的区别(不只是参数位置)
很多人以为 GET 和 POST 的区别只是"参数在 URL 里还是请求体里",实际上差异远不止于此:
| 对比项 | GET | POST |
|---|---|---|
| 参数位置 | URL 查询字符串(?key=value) | 请求实体主体中 |
| 数据大小限制 | 受 URL 长度限制(约 2KB~8KB) | 理论上无限制 |
| 缓存行为 | 可被浏览器缓存 | 通常不被缓存 |
| 书签/历史记录 | 参数保留在 URL,可收藏 | 参数不在 URL,不可直接收藏 |
| 幂等性 | 幂等 | 非幂等 |
| 安全性 | 安全(不修改服务器) | 非安全(会修改服务器) |
| 用途 | 查询、读取 | 提交、创建 |
飞翔公司场景:图妹在后台查询"本月活动列表",用 GET,URL 是
/api/activities?month=2026-06。波比"创建新活动",用 POST,数据在请求体中:{"title":"飞翔年中庆","budget":50000}。
幂等性(Idempotency)
幂等性是指:同样的操作执行一次和执行多次,对服务器资源产生的结果相同。
| 方法 | 是否幂等 | 解释 |
|---|---|---|
| GET | ✅ 幂等 | 查 1 次航仔资料和查 100 次,结果一样 |
| POST | ❌ 非幂等 | 波比提交 1 次请假单 = 1 条记录,提交 100 次 = 100 条记录 |
| PUT | ✅ 幂等 | 航仔把个人简介改成"擅长 Go 语言",改 1 次和改 10 次,最终都是"擅长 Go 语言" |
| DELETE | ✅ 幂等 | 删除一篇草稿,删 1 次是"已删除",删 100 次还是"已删除"(不会报错) |
| PATCH | ❌ 非幂等 | 对余额做"加 100 元"操作,执行多次就会加多次 |
生活比喻:幂等就像按电梯按钮——你按 1 次和按 10 次,电梯都只会在你那一层停 1 次。非幂等就像往存钱罐里投硬币——投 1 次多 1 元,投 10 次多 10 元。
安全性(Safety)
安全性是指:方法不会修改服务器上的资源状态。
| 方法 | 是否安全 | 解释 |
|---|---|---|
| GET | ✅ 安全 | 只读,服务器数据纹丝不动 |
| POST | ❌ 不安全 | 会创建新资源,改变服务器状态 |
| PUT | ❌ 不安全 | 会覆盖旧资源,改变服务器状态 |
| DELETE | ❌ 不安全 | 会删除资源,改变服务器状态 |
注意:安全性和幂等性是两个独立的概念。GET 既安全又幂等;DELETE 幂等但不安全(会删除数据);POST 既不安全也不幂等。
飞翔公司场景化示例
RESTful API 设计原则
REST(Representational State Transfer,表述性状态转移) 是一种 API 设计风格,核心思想是:用 URL 定位资源,用 HTTP 方法描述对资源的操作。
| 操作 | HTTP 方法 | URL 示例 | 说明 |
|---|---|---|---|
| 查询所有员工 | GET | /api/employees | 安全、幂等 |
| 查询单个员工 | GET | /api/employees/hangzai | 安全、幂等 |
| 创建员工 | POST | /api/employees | 非安全、非幂等 |
| 更新员工(全量) | PUT | /api/employees/hangzai | 非安全、幂等 |
| 更新员工(部分) | PATCH | /api/employees/hangzai | 非安全、非幂等 |
| 删除员工 | DELETE | /api/employees/hangzai | 非安全、幂等 |
飞翔公司场景:翼王 review 后端接口设计时,看到
/api/getUserInfo这种 URL 就会拍桌子——RESTful 风格应该是GET /api/users/{id},把动作交给 HTTP 方法,URL 只表示资源。
本篇小结
- HTTP/1.1 定义了 8 个标准方法:GET、POST、PUT、DELETE、HEAD、OPTIONS、TRACE、CONNECT
- GET 用于查询,POST 用于创建,PUT 用于更新,DELETE 用于删除
- 幂等性:多次执行结果相同(GET、PUT、DELETE 幂等;POST、PATCH 非幂等)
- 安全性:不修改服务器状态(GET 安全;POST、PUT、DELETE 不安全)
- GET 和 POST 的区别不仅是参数位置,还包括缓存、书签、幂等性、安全性等多个维度
- RESTful 设计原则:URL 表示资源,HTTP 方法表示操作
动手实践
温馨提示: 以下实践示例中涉及的域名(如
www.feixiang.net)、公司场景和接口均为虚构数据,仅用于演示协议原理,实际执行时可能不会产生文档中描述的效果。建议将命令中的域名替换为你自己可访问的真实地址进行练习。
实践:用 curl 测试不同方法
# GET 请求 - 查询飞翔官网
curl -X GET http://www.feixiang.net
# POST 请求 - 提交数据(假设有测试接口)
curl -X POST http://api.feixiang.net/test \
-H "Content-Type: application/json" \
-d '{"name":"波比","event":"飞翔年中庆"}'
# HEAD 请求 - 只获取响应头
curl -I http://www.feixiang.net
# OPTIONS 请求 - 查看支持的方法
curl -X OPTIONS -v http://api.feixiang.net/test 2>&1 | grep Allow
实践:观察浏览器表单的行为
创建一个简单的 HTML 文件,分别用 GET 和 POST 提交表单,观察浏览器地址栏的变化:
<!-- GET 表单:提交后参数会显示在 URL 中 -->
<form action="/search" method="GET">
<input name="keyword" value="飞翔科技">
<button type="submit">GET搜索</button>
</form>
<!-- POST 表单:提交后参数在请求体中,URL 不变 -->
<form action="/apply" method="POST">
<input name="name" value="波比">
<button type="submit">POST申请</button>
</form>
实践:思考题
- 为什么银行转账接口通常用 POST 而不是 PUT?(提示:考虑幂等性,如果转账请求超时重发会怎样?)
- 靓晴要设计一个"点赞"功能,用 POST 还是 PUT 更合适?点赞两次应该算两次赞还是一次赞?
- 假设凌叔写了一个自动重试机制:网络超时后自动重发请求。哪些方法是"重试安全"的?哪些需要额外处理?