JSON、表单与图片接口的响应怎么统一:状态码、错误体与缓存头的分工
同一服务返回 JSON、表单结果或图片时,响应规范应先统一状态码语义、错误载体和缓存边界,再按媒体类型定义成功载荷;API.PLUS 的具体端点与字段本次材料未提供,需待核实。
结论先说:同一服务里,JSON、表单和图片接口不必共用同一种成功响应,但应共用同一套“失败语义”。先约定状态码表达结果类别、错误响应默认用可解析的 JSON(浏览器表单可按 Accept 返回 HTML)、缓存头只加在可缓存的成功响应上,再分别定义各媒体类型的成功载荷。API.PLUS 的具体端点、字段名与错误码,本次材料未提供,需以其文档为准;下文示例均为演示,未实际调用。
统一层:先定三件事#
- 状态码:按通用 HTTP 语义,2xx 表示成功,4xx 表示客户端问题,5xx 表示服务端问题。不要用 200 包住失败。若历史客户端只能读 200,必须在响应体写明
success:false并在文档标注;两种语义不能混用。 - Content-Type:JSON 成功响应用
application/json;表单成功页用text/html,或返回 JSON;图片成功响应用image/*。客户端先看状态码和 Content-Type,再决定解析分支。 - 错误体:建议固定
code、message、request_id,details可选。字段名是演示,不是 API.PLUS 的实际契约。
以下为演示响应,未实际执行,也不是真实接口返回:
HTTP/1.1 422 Unprocessable Content
Content-Type: application/json
Cache-Control: no-store
{
"code": "invalid_field",
"message": "字段校验失败",
"request_id": "req_demo_001",
"details": [{"field": "email", "reason": "格式无效"}]
}
三种成功响应的边界#
JSON:返回对象,列表放在明确字段里
建议成功响应返回对象而不是裸数组,例如用 items 承载列表,用 page、page_size、total 或游标字段表达分页。这样以后增加字段不必改变顶层类型。业务错误不要塞进 200,除非有明确兼容条件。
表单:浏览器与 API 客户端分开处理
浏览器表单 POST 成功后,常用 303 See Other 跳转到结果页;API 客户端提交表单时,可返回 200 JSON 或 204 No Content。校验失败返回 422:面向浏览器可返回 HTML 表单并保留输入,面向程序则返回 JSON 错误体。响应 Content-Type 必须与实际内容一致,不要把错误 HTML 放在 JSON 接口里返回 200。
图片:成功给二进制,失败给 JSON
图片成功响应用 200 加 image/jpeg、image/png 等;图片不存在或参数错误时,返回 4xx/5xx 加 JSON 错误体,而不是 200 占位图掩盖失败,除非产品明确把占位图定义为成功语义。需要图片元数据时,用 Accept: application/json 或查询参数返回 JSON(例如含图片 URL),不要让同一个 body 同时混放二进制和 JSON。图片成功响应可带 ETag 与缓存头;错误响应建议 no-store。具体 TTL 取决于内容是否可变,待核实。
| 类型 | 成功响应 | 失败响应 | 缓存注意 |
|---|---|---|---|
| JSON | 200 + application/json | 4xx/5xx + JSON 错误体 | 按业务决定;敏感数据 no-store |
| 表单 | 303 到结果页,或 204/200 JSON | 422 + HTML 或 JSON | 结果页按页面策略 |
| 图片 | 200 + image/* | 4xx/5xx + JSON | 成功可缓存,错误 no-store |
一致性检查#
- 客户端能否只凭状态码和 Content-Type 选择解析分支?
- 错误体是否都带
request_id,便于排查? - 图片错误响应是否不会被 CDN 或浏览器当成图片长期缓存?
- 浏览器表单和 API 客户端是否各有明确且不混淆的路径?
先统一失败语义,再允许成功载荷按媒体类型不同;这比强求三种接口返回同一种 body 更可维护。API.PLUS 的实际规范仍需核对其接口文档。