同样是失败,一会儿 200 + success:false,一会儿 4xx + JSON,前端没法统一分支。先约定:状态码诚实 + 体按 data/error 对称。
把一条响应像抓包一样展开
一条 HTTP 响应是可读文本:状态行(HTTP 版本 + 状态码 + 原因短语)、响应头、空行、可选响应体。选一个场景,点「解析响应」,看状态码如何决定响应体的形状——2xx 带 data,4xx/5xx 带 error;全程 200 塞 success:false 会让契约裁定直接转红。
选一个场景(像在 Network 面板挑一条响应)
发生了什么
GET /api/projects 拿到 2 个项目。
响应消息预览待解析
HTTP/1.1 200 OKContent-Type: application/json选好左侧场景,点「解析响应」把消息像抓包一样展开。尚未解析。选一个场景,点「解析响应」把响应像抓包一样展开成状态行、头、空行、体。
响应消息的四段与载荷契约
实验台里每一段都对应响应文本的一个区域;下面给它们命名,并补充面板里看不见的两点。
- 状态行:HTTP 版本 + 状态码 + 原因短语,是消息的第 1 行(HTTP/1.1 200 OK)。状态码表达结果类别——成功、重定向、客户端错、服务端错;结果类别的取舍由 status-code 卡负责。
- 响应头:每行一个 名: 值。Content-Type 描述体格式,Content-Length 给字节长,Cache-Control/ETag 影响后续命中,Location 配 3xx 指向新地址,Set-Cookie 写会话凭据。
- 空行:告诉客户端「头结束了,后面如果有内容就是体」;缺了会让体被误读进头部。
- 响应体:可选。2xx 把返回数据放进 data,4xx/5xx 把错误放进 error;204/304 等可以没有体。
- data vs error 契约(核心):成功返 { data } 或 { data, error: null },失败返 { data: null, error: { code, message } }——结构对称,前端只按状态码分流就能统一解析。
什么时候要看响应这一半
当你设计接口返回、读 Network 面板的 Response、或纠结错误该塞在哪时,先把响应拆成这四段。
HTTP 层的缓存、自动重试、监控都读状态码。错误被塞进 200 的体里,这些机制会把失败当成功放行。
从结果到一条可解析的响应
最短路径是:定结果类别 → 选状态码 → 让体的形状跟随状态码 → 用头部描述体 → 核对 data/error 对称。
- 定结果类别:成功用 2xx,重定向用 3xx,客户端输入/身份/权限问题用 4xx,服务端临时未能完成用 5xx。
- 让体跟随状态码:2xx 的体放 data(资源或列表),4xx/5xx 放结构化 error;error.message 面向用户,error.code 面向程序。
- 用头部描述体:Content-Type 与真实格式一致;新建加 Location;可缓存加 Cache-Control/ETag;可重试加 Retry-After。
- 体可空时明确空:204 No Content / 304 Not Modified 不要再塞 JSON,Content-Length: 0。
- 核对:在 Network 面板看真实响应文本,确认四段层次清楚、状态码与体不互相打架。
同一处错误,只改状态码与体的契约
两条按钮把场景载入上方实验台;点「解析响应」看契约裁定长在响应消息物件上。
提交缺 name 时返回 400,体是 { data: null, error: { code, message, field } }。前端按状态码进入错误分支,按 error.code 定位输入框。
同样的错误却用 200,把 success:false 塞进体。HTTP 层的重试、缓存、监控都把它当成功放行,前端还得逐个接口判 success 字段。
快速自测
服务端创建资源成功,哪种响应最能让客户端正确处理?
继续查证
术语的技术定义和行为以这些一手或权威资料为准。
下一步学
和本知识点经常一起出现的概念。