在 javascript 中实现 fetch api 的请求数据预异常处理,核心做法是在 fetch 调用链的 .then() 阶段拦截 http 错误状态码(如 4xx、5xx),并在 .catch() 阶段捕获网络级故障。具体而言,需要在解析 json 之前检查 response.ok 属性,若为 false 则主动抛出包含状态码和文本的错误对象,从而将 http 错误转化为可被统一处理的异常流程。

如何区分网络错误与 HTTP 状态码错误
Fetch API 默认仅在发生网络中断或 CORS 策略阻止时才会触发 reject,而不会因服务器返回 404 或 500 等状态码而自动报错。要区分这两者,必须在获取响应后立即检查 response.status 或 response.ok。如果状态码不在 200-299 范围内,应手动抛出 Error 实例,这样后续的 .catch() 就能统一捕获到所有类型的失败,包括网络断开和服务器拒绝。

async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Fetch failed:', error.message);
throw error;
}
}
上述代码展示了标准的异步处理模式。当 fetch 成功获取响应但状态码为 404 时,if (!response.ok) 条件成立,程序进入 throw 分支。此时 await response.json() 不会被执行,控制流直接跳转至 catch 块。这种结构确保了无论是因为 DNS 解析失败导致的网络错误,还是服务器返回的错误页面,调用者都能通过同一个 catch 逻辑进行处理。
立即学习“Java免费学习笔记(深入)”;
如何在异常处理中保留原始响应体信息
当服务器返回非 2xx 状态码时,响应体中往往包含具体的错误描述(如 JSON 格式的 {"message": "User not found"})。为了在异常处理中获取这些详细信息,需要在抛出错误前读取并解析响应体。由于 response.text() 或 response.json() 只能被消费一次,因此必须先将响应克隆或使用 response.clone(),或者直接在判断状态码后尝试解析正文,再将解析出的内容附加到错误对象中。

async function fetchWithErrorBody(url) {
try {
const response = await fetch(url);
let data;
try {
data = await response.json();
} catch (e) {
data = null;
}
if (!response.ok) {
const errorMessage = data?.message || `HTTP ${response.status}`;
throw new Error(errorMessage, { cause: { status: response.status, body: data } });
}
return data;
} catch (error) {
console.error('Request failed:', error.cause?.status, error.message);
throw error;
}
}
该方案通过嵌套的 try...catch 安全地尝试解析 JSON。即使响应体不是合法的 JSON,也不会导致程序崩溃,而是将 data 设为 null。随后根据 response.ok 检查结果,提取 data.message 作为主要错误信息,并将完整的状态码和原始响应体存储在 cause 属性中。这种做法允许上层调用者在捕获异常后,依然能够访问服务器返回的详细错误上下文,便于前端展示友好的错误提示或进行日志记录。
基于 response.ok 为 false 时的具体处理结果是什么
当 response.ok 为 false 时,意味着请求虽然到达了服务器且服务器已返回响应,但状态码表示客户端错误或服务器内部错误。在此条件下,程序会执行手动抛出的 Error 对象,导致 await response.json() 被跳过。最终结果是调用者接收到的不是一个有效的数据对象,而是一个包含 HTTP 状态码信息的 Error 实例。这改变了默认的静默失败行为,使得开发者可以在 UI 层根据状态码显示不同的错误界面,例如对 401 显示登录框,对 500 显示系统维护提示。


















