GET 与 POST 请求示例怎么调试:先抓真实请求,再逐项加回
一句话回答
调试 GET 与 POST 的关键,是把代码里"以为发出的请求"换成可重放的最小请求:固定方法、完整 URL、请求头、body 原文与期望响应,再逐项加回参数。GET 的主要风险在 URL 编码与敏感信息,POST 的主要风险是 body 与 Content-Type 不一致;2xx、301/302、401/403 都容易造成误判。文中示例为未执行的示意,使用占位域名与占位密钥,具体 API 的参数与错误码需以该服务文档为准。
核心要点 TL;DR
- 可重放的请求记录应包含方法、完整 URL、请求头、body 原文和期望响应五项。
- POST 的 body 形态必须与 Content-Type 匹配,否则服务端可能读到空 body 或解析失败。
- xx 不代表业务成功,301/302 后方法可能被改写,需看响应头与 body 再下结论。
调试 GET / POST 请求,先别急着读响应体:把代码\"以为发出的请求\"变成一条可重放的请求,再逐项对照响应。下面所有示例都是未执行的示意,使用 example.com 与 YOUR_KEY 占位,不代表对任何具体服务的实测结论;具体 API 的参数名、鉴权方式和错误码,需以该服务文档为准。
一条可重放的请求要记哪些东西#
缺任何一项,别人复现时都只能靠猜:
- 方法:GET 还是 POST,有没有被客户端改写过。
- 完整 URL:含查询串,注意参数顺序与原样编码。
- 请求头:至少 Content-Type、Accept、鉴权头,以及自定义头。
- body 原文:不是对象,是最终发出的字节。
- 期望响应:状态码、关键响应头、body 片段。
# 未执行示例:占位域名与占位密钥
curl -sS -i -X POST 'https://api.example.com/v1/items?dry_run=1' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_KEY' \
--data '{"name":"demo","tags":["a","b"]}'
-i 让响应头一并输出,很多问题在头里就能看出来。
GET:问题多数在 URL 里#
- 编码:空格、
&、=、中文、+都需要正确编码,手工拼接查询串最容易在这里出错。 - 重复键与数组:
tag=a&tag=b还是tag[]=a&tag[]=b,由服务端约定,不能自行假定。 - 敏感信息:查询串会进入访问日志、浏览器历史与 Referer,密钥类参数不宜放在这里。
- 缓存:GET 通常被视为可缓存,调试时可能读到中间层缓存而非源站响应,必要时加随机参数或看响应头确认。
POST:body 与 Content-Type 必须一致#
| Content-Type | body 形态 | 常见误用 |
|---|---|---|
| application/json | JSON 文本 | 声明了 json 却发送表单串,服务端解析失败或读到空值 |
| application/x-www-form-urlencoded | 键值对,已编码 | 直接贴 JSON,键名被当成一个整体 |
| multipart/form-data | 带 boundary 的分段 | 手写 boundary 与头不一致,文件字段缺失 |
表单编码与 JSON 之间不存在隐式转换,Content-Type 就是服务端选择解析器的依据。
调试步骤#
- 打印或抓包拿到实际发出的请求,而不是代码里写的对象。
- 用 curl 或同类工具最小化重放,只保留必需头和最小 body。
- 逐项加回:先鉴权头,再 body 字段,再可选参数,定位到具体哪一项改变结果。
- 分三层看响应:状态码、响应头(重定向、缓存、限流相关字段)、body。
- 记录环境:客户端版本、是否经过代理或网关。服务端版本与限流阈值属待核实信息。
三个容易误判的现象#
- 301 / 302 之后方法被改写:部分客户端会把 POST 跟随重定向时降级为 GET,导致 body 丢失。是否发生取决于客户端与状态码,需按实现核实。
- 2xx 不等于业务成功:不少接口用 200 返回业务错误码,必须读 body。
- 401 与 403:通常分别表示未通过认证与已认证但无权限,但并非所有服务严格遵守这条划分,以文档为准。
边界说明#
本文没有执行任何请求,也没有联网核验任何服务的当前行为。涉及具体端点、配额、超时与重试策略时,应补上幂等键并确认服务端是否支持,这些都需要以目标服务文档和自建测试记录为依据。
常见问题(FAQ)
GET 请求可以带 body 吗?
HTTP 语义上 get 的 body 没有定义用途,不同客户端与中间层处理方式不一致,部分实现会直接丢弃。示例与生产代码都不建议依赖它;若确实需要传结构化数据,优先用 POST 或把参数放进查询串。
为什么用 curl 能通,代码里却报错?
常见差异在请求头(Content-Type、Accept、UA)、URL 编码方式、是否跟随重定向、代理设置与超时值。先把代码实际发出的请求打印或抓包出来,与 curl 的请求逐项对照,再缩小范围。