响应状态码|HTTP协议篇
# 响应状态码
30 秒速记
- 响应状态码位于响应报文中,用三位十进制数字概括服务器的处理结果。
- 状态码范围按首位分成五类,即
1xx到5xx;原因短语只是可自定义的文字说明。 2xx表示请求成功,常见值包括200、204和206。3xx表示重定向相关结果,常见值包括301、302和304。4xx指向客户端侧错误,5xx指向服务器侧错误;典型值分别有400、403、404与500、501、502、503。
响应状态码是响应报文里的三位十进制数字,用来概括服务器处理这次请求的结果。 看首位就能判断大方向:2xx 表示成功,3xx 涉及重定向或缓存复用,4xx 和 5xx 分别表示客户端侧与服务器侧问题;1xx 则是中间状态。工程里我会直接判断数字,而不会依赖原因短语,因为它可以自定义,并且在 HTTP/2、HTTP/3 中不再按传统形式传输。还要注意,204 没有正文,304 主要服务于条件缓存,接口返回 200 也不代表业务一定成功。
- 状态码在响应报文里表示了服务器对请求的处理结果;
- 状态码后的原因短语是简单的文字描述,可以自定义;
- 状态码是十进制的三位数,分为五类,从
100到599; 2××类状态码表示成功,常用的有200、204、206;3××类状态码表示重定向,常用的有301、302、304;4××类状态码表示客户端错误,常用的有400、403、404;5××类状态码表示服务器错误,常用的有500、501、502、503

原理拆解: 状态码位于响应起始行,是服务器对本次 HTTP 处理结果的协议级分类。1xx 表示中间状态,2xx 表示请求已成功处理,3xx 涉及后续定位或缓存复用,4xx 表示当前请求存在客户端侧问题,5xx 表示服务器未能正常完成处理。客户端应以数字状态码及响应语义为准,不能依赖可被修改、甚至在 HTTP/2 和 HTTP/3 中不再以传统原因短语形式传输的说明文字。
最小验证: 输入四个本地路径,验证客户端能够收到 200、204、404 和 500,同时观察 204 没有响应体。以下 JavaScript 可直接由 Node.js 运行。
const http = require('node:http');
const server = http.createServer((req, res) => {
if (req.url === '/ok') {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('saved');
} else if (req.url === '/empty') {
res.writeHead(204);
res.end();
} else if (req.url === '/error') {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('internal error');
} else {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('not found');
}
});
server.listen(0, async () => {
const { port } = server.address();
for (const path of ['/ok', '/empty', '/missing', '/error']) {
const response = await fetch(`http://127.0.0.1:${port}${path}`);
console.log(path, response.status, JSON.stringify(await response.text()));
}
server.close();
});
关键行是 writeHead,它确定响应状态;预期依次打印 200 "saved"、204 ""、404 "not found" 和 500 "internal error"。fetch 对 404、500 不会自动抛出异常,调用方必须检查 response.ok 或 response.status。
边界与排查: 204 成功但不携带正文,206 只表示部分内容;304 主要用于条件请求的缓存复用,不应简单理解为页面跳转。401、403 和 404 的含义也不同,分别偏向认证、拒绝访问和资源不存在。业务接口即使返回 200,正文仍可能表达业务失败,因此协议状态与业务状态需要分层判断;排查时应同时核对状态码、响应头、正文及重定向链。
面试官追问
追问 1文件下载页收到 206 后,前端监控因为状态不是 200 就标记失败,而文件分片实际可用,你会如何纠正规则?
206 属于成功类状态,表示本次返回部分内容,不能用“是否等于 200”替代协议语义判断。监控应先按状态码类别识别成功,再结合下载场景验证分片响应;若业务要求完整文件,还需额外检查范围与内容,不能仅凭 2xx 宣告业务完成。
追问 2一个批量删除接口返回 204,页面统一执行 response.json() 后进入异常分支,后端认为状态码已经表示成功,你会改哪一层?
前端应针对 204 跳过正文解析,因为它表示成功但不携带响应体,空内容本身不是请求失败。通用请求封装可先检查 response.status,再决定是否解析正文;若产品确实需要返回删除统计,则应调整接口契约和状态码,而不是伪造 JSON 占位。
追问 3旧客户端把 301、302、304 都当成页面跳转,新缓存策略上线后大量 304 被错误导航,你会怎样划清边界?
应把 304 从普通跳转逻辑中拆出,它主要服务于条件请求的缓存复用,不等同于要求客户端访问新地址。客户端需要结合响应头和请求上下文处理 3xx;仅按首位数字统一跳转会丢失具体语义,也可能破坏缓存链路。
追问 4线上 fetch 请求持续收到 404 和 500,但 catch 中没有任何日志,值班同学断言浏览器吞掉了异常,你怎么排查?
先检查调用方是否读取了 response.ok 或 response.status,因为 fetch 收到 404、500 时通常不会仅因 HTTP 错误自动抛出异常。随后核对响应头、正文和重定向链;只有网络级失败与协议级失败分开记录,监控才不会漏掉已正常返回的错误响应。
追问 5支付接口统一返回 200,再用正文里的 code 表示扣款失败;监控团队想只看 HTTP 状态判断成功率,你会接受吗?
不能只看 HTTP 状态,因为 200 仅说明协议层请求已成功处理,正文仍可能表达业务失败。监控应分别记录协议状态和业务状态,并明确两者的聚合口径;若强行合并,会把业务拒绝统计为成功,也可能把正常的客户端错误误报为服务故障。
追问 6网关告警只覆盖 500,一次故障主要返回 502 和 503,负责人却认为它们不是应用抛出的异常就无需纳入,你怎么评审?
该规则会漏掉服务器侧未能正常完成处理的响应,因为 500、501、502、503 都属于 5xx。告警应先覆盖整个服务端错误类别,再按具体码值定位来源;但 5xx 只给出协议级分类,最终归因仍要结合网关、上游和响应内容。
