HTTP 状态码是一份比大多数使用它的公司还古老的契约。多数 API 靠几个码活下来——但在每个决策点选对码,会直接改变客户端、缓存和监控系统的行为。下面是实用子集,以及每个码背后的决策。
成功码:200、201、204
- 200 OK —— 默认成功,带结果响应体。
- 201 Created —— POST 创建了资源。配合
Location头指向新资源,跟随链接的客户端自动获得正确行为。 - 204 No Content —— 成功且无话可说:DELETE 的确认、客户端已知晓状态的 PUT 更新。省一次空响应体的往返。两个注意点:204 不能携带响应体;对 204 调
await res.json()会抛错——客户端要按状态码分支。
重定向:方法保留矩阵
重定向码之间有一个被忽视就毁 API 的差别:请求方法是否保留。
| 码 | 含义 | 方法保留? | 被缓存? |
|---|---|---|---|
| 301 | 永久移动 | 常被改写成 POST→GET | 是,激进缓存 |
| 302 | 临时移动 | 常被改写成 POST→GET | 否 |
| 307 | 临时重定向 | 严格保留 | 否 |
| 308 | 永久重定向 | 严格保留 | 是 |
API 版本迁移(/v1/… → /v2/…)用 308——POST 被改写等于一次损坏的 API 调用。页面搬家用 301 就好,它的激进缓存反而是特性。迁移时用 URL 解析器检查重定向链——意外的二次跳转会让延迟翻倍。
4xx 家族:把意思说准
- 400 Bad Request —— 语法错误。客户端原样重试也没用时,就返回 400。
- 401 与 403 —— 401 = “你是谁?“(未认证,配
WWW-Authenticate头);403 = “知道你是谁,不行”(未授权)。混用会让错误日志变成噪音。 - 404 与 410 —— 404 表示不存在、可能暂时不存在;410 Gone 告诉缓存和爬虫”永久移除、别再问了”——比 404 更快让过期内容退出索引。
- 429 Too Many Requests —— 限流码,永远带上
Retry-After。尊重它的客户端是在帮你;把尊重它的成本降到最低。
5xx 家族与监控的分工
500 是笼统的崩溃;502/504 表示上游/网关失败(代理在说”我后面的应用挂了或太慢”);503 表示主动不可用(维护或过载,配 Retry-After)。监控分工:5xx 突增呼叫值班;4xx 突增立案调查但不呼叫——通常意味着客户端版本 bug、恶意爬虫或 token 风暴。
状态码还是缓存契约
缓存靠状态码决定存不存:带新鲜头的 200 可缓存;301 被激进缓存;404/410 会被很多 CDN 缓存(缓存住的 404 能活得比修复更久——发布后记得刷新缓存);5xx 绝不可缓存。“我们修好了但部分用户还看到旧响应”,第一个嫌疑人就是状态码及其缓存策略。完整的 HTTP 状态码速查收录了每个码的缓存与方法规则,契约一查即得。