前端收到 200 OK,响应体却写着 Internal Server Error。图里的服务端把错误写进了 JSON,HTTP 状态仍然是成功;前端如果只判断状态码,就会继续执行成功分支。

JSON 里的 status 只是一个普通字段。它叫 status、code 还是别的名字,由接口自己约定,网关和浏览器不会据此改写 HTTP 状态。于是服务端已经失败,按 HTTP 状态统计的监控却还在记成功请求。
对于图中这种未处理的服务器异常,我会直接返回 HTTP 500,响应体负责补充错误信息:
HTTP/1.1 500 Internal Server Error
Content-Type: application/json
{"code":"SERVER_ERROR","message":"服务暂时不可用"}HTTP 状态表达请求结果,业务码说明具体原因。例如未认证用 401,资源冲突用 409;不必把所有失败都装进 200,再要求每个调用方另写一遍识别逻辑。
前端也有一个容易漏掉的细节:fetch() 收到 HTTP 500 时,通常仍会正常返回 Response。它不会替业务代码抛异常,需要检查 response.ok:
const response = await fetch(url);
if (!response.ok) {
throw new Error(`请求失败:HTTP ${response.status}`);
}
const data = await response.json();这段写法先判断状态,因此也能处理代理返回 HTML 错误页的情况,不会在读取 JSON 时把真正的 HTTP 错误盖过去。网络断开等导致的 fetch() 异常,和这里主动抛出的异常,可以交给调用方同一处捕获。
如果旧接口已经约定了“200 + 业务码”,客户端就必须在统一请求封装里判断业务码,监控也要统计业务失败。直接改变状态码会影响已有的异常处理和重试逻辑,应随接口升级一起改。新接口则没有必要继续沿用这层歧义。
评论 (0)