HTTP 状态码与方法语义:一次搞懂所有基础概念
一句话结论(30s)
状态码的「首数字」决定类别——1xx 信息 / 2xx 成功 / 3xx 重定向 / 4xx 客户端错 / 5xx 服务端错;方法的本质由「安全」(是否改数据)和「幂等」(重复执行副作用是否相同)两个维度刻画。因为排障时先看首数字就能立刻定位是客户端还是服务端的责任,而设计接口时只有吃透幂等(PUT 幂等、POST 不幂等)才能避免重复提交产生脏数据。
核心原理(2min)
- 状态码分类:1xx 信息、2xx 成功(200/201/204)、3xx 重定向(301/302/304)、4xx 客户端错(400/401/403/404)、5xx 服务端错(500/502/504)。
- 301 vs 302:301 永久,浏览器缓存 + SEO 权重传递(HTTP→HTTPS 跳转用它);302 临时,每次回源、不传权重(登录后跳转用它)。
- 502 vs 504:502 是上游返回了无效响应(进程崩溃/连接重置),504 是上游超时内没有任何响应(慢 SQL/长事务/OOM 前兆)。
- 方法语义:GET/HEAD 安全且幂等,PUT/DELETE 不安全但幂等,POST/PATCH 既不安全也不幂等。
- GET vs POST:GET 参数在 URL(可缓存/可书签/有长度限制,敏感数据禁用),POST 参数在 body(不可缓存、无硬限制)。
底层深入(5-10min)
状态码分类
| 范围 | 类别 | 典型 |
|---|---|---|
| 1xx | 信息 | 101 Switching Protocols |
| 2xx | 成功 | 200 OK, 201 Created, 204 No Content |
| 3xx | 重定向 | 301 永久, 302 临时, 304 Not Modified |
| 4xx | 客户端错误 | 400 Bad Req, 401 未认证, 403 无权限, 404 不存在 |
| 5xx | 服务端错误 | 500 内部错误, 502 Bad Gateway, 504 Gateway Timeout |
301 vs 302
301 永久重定向:浏览器会缓存——下次直接走新 URL,不经过服务器。搜索引擎更新索引用新 URL(SEO 权重传递)。
302 临时重定向:浏览器不缓存——每次仍先访问旧 URL。搜索引擎保留旧 URL(不传递权重)。
HTTP→HTTPS 强制跳转用 301。登录后页面跳转用 302。
思考:为什么浏览器敢「缓存」301 却不敢缓存 302?因为语义不同——301 承诺「这个地址永久搬走了」,浏览器记住新地址可以省掉以后每次回源;302 只说「临时去那边一下」,随时可能改回来,缓存了就会错过变化。所以 SEO 也只对 301 传递权重:永久迁移才值得把旧页面的权重「过户」给新 URL。
502 vs 504
502 Bad Gateway:Nginx 将请求转发给上游服务(如 Tomcat),上游返回了无效响应(进程崩溃、发送了非 HTTP 数据、连接被重置)。
504 Gateway Timeout:Nginx 将请求转发给上游服务,上游在超时时间内没有返回任何响应(进程卡顿、慢查询、OOM 前兆)。
排查方向:502 → 查上游进程是否存活。504 → 查上游是否有慢 SQL/长事务/大量 GC。
思考:502 和 504 都是「网关说上游有问题」,怎么一眼区分?看「有没有回话」——502 是上游回了,但回的是无效响应(进程崩溃、连接被重置),说明上游「活着但说错了话」;504 是上游压根没回(超时),说明上游「卡住了没说话」。所以排查方向一个是「进程还活着吗」,一个是「是不是慢 SQL/长事务/OOM 前兆」。
HTTP 方法语义
| 方法 | 语义 | 安全 | 幂等 |
|---|---|---|---|
| GET | 获取资源 | ✅ | ✅ |
| HEAD | 只获取头部 | ✅ | ✅ |
| POST | 提交/创建 | ❌ | ❌ |
| PUT | 全量更新 | ❌ | ✅ |
| DELETE | 删除 | ❌ | ✅ |
| PATCH | 部分更新 | ❌ | ❌ |
- 安全:操作不修改服务端数据
- 幂等:同样的请求执行 N 次副作用与执行 1 次相同
PUT 幂等:同一资源覆盖更新 N 次结果一样。POST 不幂等:重复提交会创建 N 个新资源。
思考:为什么「幂等」对接口设计这么重要?因为它决定了「重试安不安全」。幂等的 PUT/DELETE,客户端超时后可以放心重发,结果不会变;不幂等的 POST,重发一次就多创建一条记录。网络环境下重试是常态,设计成幂等相当于给「超时重试」发了免死金牌,否则就要靠幂等键去兜底。
GET vs POST
| GET | POST | |
|---|---|---|
| 参数位置 | URL query string | Request body |
| 可缓存 | ✅(CDN) | ❌ |
| 可书签 | ✅ | ❌ |
| 长度限制 | URL 2KB~8KB(浏览器限制) | 无硬限制 |
| 适用 | 查询、搜索、筛选 | 登录、支付、提交 |
敏感数据决不用 GET(URL 中明文暴露在浏览器历史/日志/代理缓存中)。
章末提问
Q1:301 和 302 有什么区别?分别什么场景用?
结论先行:301 是永久重定向、浏览器缓存且传递 SEO 权重,302 是临时重定向、每次回源不传权重。因为 301 承诺「永久搬走」,浏览器和搜索引擎都会记住新地址;302 表示「临时去别处」,必须每次回源查询最新跳转目标。HTTP→HTTPS 强制跳转用 301,登录后临时跳转用 302。
Q2:502 和 504 的区别?分别怎么排查?
结论先行:502 是上游返回了无效响应,504 是上游超时没响应。因为 502 说明上游「回话但回错了」(进程崩溃、连接重置),504 说明上游「没回话」(卡顿、慢 SQL、OOM 前兆);所以 502 查上游进程是否存活,504 查是否有慢 SQL/长事务/大量 GC。
Q3:什么是幂等?PUT 和 POST 的幂等性有什么区别?
结论先行:幂等 = 同样的请求执行 N 次和执行 1 次副作用相同;PUT 幂等、POST 不幂等。因为 PUT 是「覆盖更新同一资源」,重复覆盖结果不变;POST 是「创建新资源」,每执行一次就多一条记录。理解幂等才能在网络重试场景下避免重复提交产生脏数据。