语义差别
GET 用于读取,参数在 URL(查询串),应安全且幂等——多次调用不改变服务端状态。POST 用于提交,数据放请求体,可能产生副作用(新建订单、改数据)。
工程上的差别
| 维度 | GET | POST |
|---|---|---|
| 参数位置 | URL 查询串 | 请求体 |
| 可缓存 | 是 | 否 |
| 浏览器历史 | 会留存 | 不留敏感体 |
| 长度限制 | 受 URL 长度约束 | 基本无限制 |
| 幂等 | 应幂等 | 不保证 |
两个常见误用
- 用 GET 改数据:搜索引擎爬虫或预加载会误触发删除、扣款;
- 用 POST 做纯查询:丧失缓存与可分享链接,列表筛选本可用 GET。
一句话原则
读用 GET,写用 POST;需要幂等且安全的重复操作优先 GET,有副作用的提交用 POST。
实战案例:三个选错方法的代价
- 用 GET 做删除:链接被浏览器预取或爬虫抓取,用户还没点数据就没了。任何有副作用的操作都必须用 POST / PUT / DELETE。
- 用 POST 做搜索:结果页无法收藏、无法分享、无法被缓存,刷新还会提示“重新提交表单”。筛选与分页应走 GET 查询串。
- 在 GET 上放敏感参数:token 或手机号会留在浏览器历史、代理与服务器日志里。敏感数据应放在请求体或请求头。
常见问题(FAQ)
POST 比 GET 安全吗?并不更安全,只是参数位置不同;两者都必须走 HTTPS。GET 有长度限制吗?规范没有硬限制,但浏览器与服务器通常在 2–8KB 之间截断,超长参数应改用 POST。“幂等”是什么意思?重复执行结果一致;GET / PUT / DELETE 应幂等,POST 通常不保证,所以重试要配幂等键。表单默认用哪个?HTML 表单未写 method 时默认 GET,提交敏感信息前务必改成 POST。
安全与可缓存性的再平衡
方法选择还牵动两件常被忽略的事:
- 敏感参数与会话:即便用 POST,也要避免把令牌放进被日志记录的查询串;应放在请求头或请求体,并在日志中屏蔽。
- 缓存与幂等的影响面:GET 可被 CDN 与浏览器缓存,这是优点也是风险——带个性化数据的 GET 若未声明
Cache-Control: private,可能被缓存后串给他人。 - 重试语义:GET 可安全自动重试;POST 需要幂等键才能重试,否则一次“网络超时”就可能产生两笔订单。
- 预取与爬虫:浏览器与爬虫会主动抓取页面上的链接,任何有副作用的 GET 都可能被“顺手”触发。
批量与部分更新
批量创建用 POST(集合资源),部分更新用 PATCH,整体替换用 PUT,删除用 DELETE。语义混乱的常见表现是用 POST 承担所有写操作,结果是接口无法被统一处理(如无法按方法做权限与限流策略)。REST 之外,GraphQL 与 gRPC 用各自的语义表达这些意图,但“读请求幂等、写请求需幂等键”的原则同样适用。
接口设计中的一致性问题
- 同一资源用同一种方法语义:若某接口用查询串传筛选条件,其它接口也应保持一致,混用会让调用方难以形成直觉,也难以统一实现缓存与日志策略。
- 幂等性要能被验证:对声明幂等的接口,应能用自动化测试重复调用并确认结果一致,而不是只在文档里写一句“幂等”。
- 日志与审计要能还原:查询条件、请求体与响应状态都应有记录,且敏感字段需脱敏,否则出现争议时无法还原当时的请求内容。
- 限流策略按方法区分:读取类请求通常可承受更高频率,写入类请求则应更严格,限流规则与方法语义保持一致,避免误伤正常查询。
- 错误提示要指向原因:方法使用错误时应返回明确的状态码与说明,例如提示应使用另一种方法并给出正确形式,帮助调用方快速修正。
方法选择本身不难,难的是在整个接口体系里保持一致,并在文档、测试与运维策略中同步体现这一点。