HTTP 请求详解以及测试角度
1. HTTP 是什么
HTTP(Hypertext Transfer Protocol)是应用层的请求/响应协议。客户端发送请求,服务端返回响应。接口测试里关注的不是“能不能调通”这么简单,而是请求语义、状态码、Header、Body、缓存、安全、契约和副作用是否符合约定。
一个完整 HTTP 请求通常由以下部分组成:
| 组成 | 说明 | 测试关注点 |
|---|---|---|
| 请求行 | 方法、URL、HTTP 版本 | 方法是否正确,路径是否匹配,URL 编码和长度是否合规 |
| 请求头 | Content-Type、Authorization、Cookie、Accept、Origin 等 | 鉴权、内容协商、跨域、缓存、追踪字段是否正确 |
| 请求体 | JSON、表单、文件、二进制等 | Schema、必填、类型、边界、大小、编码、恶意输入 |
| 响应状态码 | 2xx、3xx、4xx、5xx | 是否能表达真实处理结果,异常是否被正确归类 |
| 响应头 | Content-Type、Cache-Control、ETag、Location 等 | 缓存、安全、重定向、资源定位、契约一致性 |
| 响应体 | 业务数据或错误信息 | 字段完整性、类型、脱敏、错误结构、兼容性 |
2. HTTP 方法
HTTP 方法表达“客户端希望服务端对目标资源做什么”。测试时不要只看接口是否返回 200,还要验证方法语义、幂等性、副作用和权限是否一致。
| 方法 | 协议语义 | 安全 | 幂等 | 请求体 | 典型场景 | 测试重点 |
|---|---|---|---|---|---|---|
| GET | 获取目标资源的当前表示 | 是 | 是 | 不建议承载业务语义 | 查询列表、查询详情 | 无副作用、参数过滤、缓存、权限隔离 |
| HEAD | 与 GET 类似,但不返回响应体 | 是 | 是 | 不建议 | 探测资源是否存在、获取元数据 | 响应体为空,响应头与 GET 一致 |
| POST | 按目标资源自身语义处理请求内容 | 否 | 否,除非业务设计幂等 | 常用 | 创建、提交、登录、复杂查询、批处理 | 重复提交、防重、参数校验、副作用 |
| PUT | 用请求内容替换目标资源当前表示 | 否 | 是 | 常用 | 全量更新、客户端指定资源 ID 的创建/覆盖 | 全量字段、重复请求一致、并发覆盖 |
| PATCH | 对目标资源做局部修改 | 否 | 取决于补丁语义和业务设计 | 常用 | 局部更新 | 未传字段保留、补丁格式、事务原子性 |
| DELETE | 删除目标资源当前表示 | 否 | 是 | 不建议承载业务语义 | 删除资源、取消绑定 | 重复删除一致、关联约束、删除后不可访问 |
| OPTIONS | 获取目标资源通信选项 | 是 | 是 | 通常无 | CORS 预检、方法探测 | Allow、CORS 头、来源校验 |
| TRACE | 回显请求路径上的消息 | 是 | 是 | 通常无 | 诊断 | 生产环境通常禁用,防 XST 风险 |
| CONNECT | 建立到目标服务器的隧道 | 否 | 否 | 特殊 | HTTPS 代理隧道 | 代理策略、内网穿透防护 |
2.1 安全方法与幂等方法
| 概念 | 方法 | 含义 | 测试判断标准 |
|---|---|---|---|
| 安全方法 | GET、HEAD、OPTIONS、TRACE | 客户端请求语义是只读,不应要求服务端改变资源状态 | 调用前后数据库、缓存、业务状态、消息、审计等无业务性变更 |
| 幂等方法 | GET、HEAD、PUT、DELETE、OPTIONS、TRACE | 多次相同请求对服务端资源的预期影响与一次请求相同 | 重复调用不产生额外资源、不重复扣减、不重复发送关键业务消息 |
| 非幂等方法 | POST 通常非幂等;PATCH 视补丁和业务而定 | 多次相同请求可能产生不同业务结果 | 需要额外验证防重、幂等键、唯一索引、状态机保护 |
注意:安全和幂等不是一回事。PUT、DELETE是幂等方法,但不是安全方法,因为它们会修改或删除资源。
3. 常见状态码
状态码是服务端对请求处理结果的协议级表达。接口测试里要避免所有异常都返回 200,也要避免把业务失败误包装成 500。
| 分类 | 含义 | 常见状态码 |
|---|---|---|
| 1xx | 请求已接收,继续处理 | 100 Continue、101 Switching Protocols |
| 2xx | 请求成功处理 | 200 OK、201 Created、202 Accepted、204 No Content |
| 3xx | 需要重定向或使用缓存 | 301 Moved Permanently、302 Found、304 Not Modified |
| 4xx | 客户端请求错误 | 400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found、405 Method Not Allowed、409 Conflict、413 Payload Too Large、414 URI Too Long、415 Unsupported Media Type、422 Unprocessable Content、429 Too Many Requests |
| 5xx | 服务端处理失败 | 500 Internal Server Error、502 Bad Gateway、503 Service Unavailable、504 Gateway Timeout、505 HTTP Version Not Supported |
3.1 状态码测试建议
| 状态码 | 适用场景 | 测试关注点 |
|---|---|---|
| 200 OK | 查询成功、操作成功且返回结果 | 响应结构、字段类型、业务数据一致 |
| 201 Created | 成功创建资源 | 是否返回资源 ID,必要时校验 Location 响应头 |
| 202 Accepted | 请求已接收,异步处理 | 后续任务状态、轮询接口、消息或任务记录 |
| 204 No Content | 成功但不返回响应体 | 响应体为空,不夹带多余 JSON |
| 304 Not Modified | 缓存命中 | ETag、If-None-Match、Last-Modified、If-Modified-Since |
| 400 Bad Request | 参数语法错误、JSON 残缺、格式非法 | 字段级错误提示,不能产生脏数据 |
| 401 Unauthorized | 未认证或认证失效 | 无 token、过期 token、签名错误 |