调接口时用 GET 还是 POST,很多人是靠习惯:能拼 query 就用 GET,要传对象就换 POST。结果参数放在 body 里发不出去、被网关拦掉、日志里查不到、缓存给串了,排查半天才发现是方法选错。这篇不背 RFC 条文,只给一套能直接用的判断标准、测试用例该覆盖哪些点,以及方法用错时典型的报错症状和排查顺序。
调接口时用 GET 还是 POST,很多人是靠习惯:能拼 query 就用 GET,要传对象就换 POST。结果参数放在 body 里发不出去、被网关拦掉、日志里查不到、缓存给串了,排查半天才发现是方法选错。这篇不背 RFC 条文,只给一套能直接用的判断标准、测试用例该覆盖哪些点,以及方法用错时典型的报错症状和排查顺序。
先说明适用范围:这套判断主要针对基于 HTTP 的常规 REST 风格接口。如果你面对的是 GraphQL、gRPC 或者已经封装好的 RPC 框架,方法选择往往由框架约定,本文的判据只能当参考。另外站内 /tools/speed-test 有现成的请求调试入口,改方法、挪参数比换脚本快,建议边看边试。
先分清:语义差异、传输差异、工程差异是三层
很多人争论 GET 和 POST 的区别时,其实在说不同层的事,谁也说服不了谁。把它们拆成三层就清楚了:语义层决定「这个操作能不能被安全重放」,传输层决定「参数能不能塞得进去」,工程层决定「中间那堆网关和缓存会怎么对待你」。测试和后端对齐时,先确认在讨论哪一层,能省掉一半的无效沟通。
- 语义层
- GET 表示「读」,可重复执行不改变服务端状态;POST 表示「提交」,一次请求可能产生副作用,重复发要自己保证幂等。
- 传输层
- GET 的入参通常跟在 URL 的查询串里,POST 的入参通常在请求体里;两者都可以带 header,别以为 POST 就不能用查询串。
- 工程层
- URL 长度上限、日志是否记录请求体、浏览器与 CDN 的缓存行为、幂等重试是否安全,这四条决定团队实际怎么写。
判断顺序建议固定成两步:先问「这个操作重放一次会不会出问题」,再问「参数放 URL 会不会太长或含敏感信息」。两个问题答完,方法基本就定了。如果两个答案互相冲突,比如是个纯查询但参数超长,那就按工程层的约束来,别硬套语义。
一张对照表定方法,再定参数放哪
方法定了之后再定参数位置,顺序别颠倒。常见错误是先想参数放哪、再倒推方法,结果就是一堆语义上明明是写操作、却因为参数少而走 GET 的接口,后面加参数时炸一片。下面这张表可以直接贴到接口评审的文档里当检查项。
| 场景特征 | 建议方法 | 参数放哪 |
|---|---|---|
| 只读查询、参数短、可缓存 | GET | 筛选、分页、排序放查询串 |
| 有副作用、参数是结构化对象 | POST | 业务字段放 body |
| 含文件上传或敏感字段 | POST | 一律放 body,不进 URL |
| 纯查询但参数超长 | POST(约定俗成) | 查询体放 body,文档标注清楚 |
- 先定方法再定参数位置,不要反过来倒推
- 同一个接口的方法一旦定下就锁死,别今天 GET 明天 POST,客户端、网关、缓存三层都会跟着出问题
- 纯查询但参数超长的场景用 POST 承载查询体,要在文档里明确标注「这是查询不是写入」,避免后来人当成写操作
- 含敏感字段的请求,不管什么方法,都不要放在 URL 里,URL 会进日志、进浏览器历史、进代理记录
- 接口文档里写清允许的方法列表,测试用例直接照着这份列表写,别靠猜
测试侧:用例要覆盖的固定几项
接口测试里关于方法的用例,不需要每个接口都写一套,但下面这几类至少要各挑一个代表接口覆盖。核心思路是:不测「文档说支持什么」,而是测「实际发出去会发生什么」。文档和实现不一致是常态,用例的价值就在于把不一致暴露出来。
- 测方法本身对同一路径分别发 GET 和 POST,确认服务端返回什么状态码,并核对允许的方法列表是否和文档一致。不一致就直接提单。
- 测参数位置把参数从查询串挪到 body、再挪回来,看是否仍然生效。只认一种位置的接口要在用例里标注,这是后续联调最容易踩的点。
- 测边界构造很长的查询串看会不会被网关截断,构造大 body 看会不会触发体积限制。同一个字段在两种方法下的表现可能完全不同。
- 测幂等与重复提交对写接口连续发两次相同请求,看是否产生两条记录;对读接口重复发两次,看结果是否一致、是否命中缓存。
如果你在测的是第三方或中转接口,方法支持和参数位置未必和上游文档一致,建议先用站内 /sites 里对应的站点条目核对一遍再动手,省得把上游的问题记到自己头上。
方法用错时的典型症状与排查顺序
大部分方法相关的故障,症状就那么几种,排查顺序固定下来能少走很多弯路。原则是从外往里看:先看客户端实际发了什么,再看中间层放不放行,最后才怀疑应用代码。反过来查,容易一开始就钻到业务逻辑里出不来。
| 症状 | 最可能的原因 | 先查哪里 |
|---|---|---|
| 返回 405 | 方法不匹配 | 核对文档与实际发出的方法 |
| 报参数缺失但你明明填了 | 参数放错位置 | 抓一次原始请求看落点 |
| 本地能通、上线就挂 | 中间层只放行某一种方法 | 网关、反向代理、应用逐层看 |
| 日志里只有 URL 没有业务字段 | 关键参数还在查询串里 | 检查参数位置与日志记录口径 |
- 返回 405 时先核对文档再核对代码里实际发出的方法,别急着改服务端
- 服务端说参数缺失,先抓一次原始请求,确认参数到底落在查询串还是 body
- 本地能通上线就挂,按网关、反向代理、应用三层逐层排查,八成是中间层限制
- 日志里只有 URL 没有业务字段,顺手把敏感字段挪进 body,再统一日志记录口径
- 同一症状在两个环境表现不同,先把两边的网关配置拉出来对比,不要只盯着应用日志
方法选错的代价不在第一次调用,而在三个月后加参数时没人记得当初为什么这么写。
最后补一句:具体某个中转站或官方接口对方法和参数的实际支持情况,各家差异不小,别拿一篇通用文章当准绳。想核对当时的实测结果,到站内 /price-watch 和 /rankings 看页面上的记录,比记忆和传言靠谱。
下一步把本文的对照表和排查顺序抄进团队的接口评审模板,再顺手测几个你正在用的接口,看看方法约定有没有和文档对不上的地方。想省事的话,站内调试入口可以直接改方法和参数位置,几分钟就能验一轮。→常见问题
GET 和 POST 到底哪个更安全?
单看方法没有绝对安全一说。参数放在 URL 里会更容易进浏览器历史、代理日志和 Referer,所以密码、令牌这类别放查询串。真正的安全保障来自传输加密和服务端鉴权,不是选哪个方法。选方法先看语义和幂等,安全是另一层的事。
接口报 405 是不是就一定是我方法用错了?
大多数情况是。405 的意思是「这个路径不允许用这个方法」,所以先核对接口文档写的是什么方法,再抓一次原始请求看实际发出去的是什么。如果两边的确一致,就要看中间层是不是把方法改写了,比如某些代理只放行 GET 和 POST。站内的 405 排查页有更细的顺序。
用 POST 传查询条件算不算错误写法?
不算错,但不标准。参数很长、又不想放进 URL 时,工程上常用 POST 承载查询体。要注意两点:一是在文档里写清这是查询不是写操作,二是别让缓存和重试逻辑把它当成写请求处理。团队内部口径统一比纠结对错更重要。