Ajax请求出错时怎么统一处理错误?

闲人耘博 阅读 53

我用原生 fetch 做 Ajax 请求,但每次都要写一遍 catch,感觉很重复。比如网络断了或者后端返回 500,我想统一弹个提示,而不是每个请求都单独处理。

试过在 fetch 外面包一层函数,但有时候错误没被捕获到,控制台报 Uncaught (in promise) TypeError: Failed to fetch,不知道是不是写法有问题。

function apiGet(url) {
  return fetch(url)
    .then(res => res.json())
    .catch(err => {
      alert('请求失败,请重试');
      throw err; // 这里加不加 throw 都有点懵
    });
}
我来解答 赞 16 收藏
二维码
手机扫码查看
1 条解答
♫海宇
♫海宇 Lv1
你的问题在于 fetch 的特性:它只有在网络完全断连时才会 reject,HTTP 返回 404、500 这些状态码时 fetch 其实是 resolve 的,不会自动抛错。所以你看到的 "Failed to fetch" 其实是网络层面的错误,但 500 错误没被捕获是因为没判断 res.ok。

正确的封装写法是这样的:

function apiGet(url) {
return fetch(url)
.then(res => {
// fetch 不会自动 reject 非 2xx 状态,必须手动判断
if (!res.ok) {
throw new Error(HTTP ${res.status});
}
return res.json();
})
.catch(err => {
// 网络错误、JSON 解析错误、HTTP 错误都会走到这里
console.error('请求失败:', err);
alert('请求失败,请重试');
throw err; // throw 出去是对的,调用方可能需要知道具体错误
});
}


调用的时候:

// 方式1:用 catch 捕获
apiGet('/api/user')
.then(data => console.log(data))
.catch(err => {
// 这里可以针对不同错误做不同处理
});

// 方式2:用 async/await
async function getData() {
try {
const data = await apiGet('/api/user');
console.log(data);
} catch (err) {
// 统一处理
}
}


关于你那个 "Uncaught (in promise)" 警告,原因是 fetch 返回的 Promise 即使 HTTP 状态码是 500 也不会 reject,但你后面 .then(res => res.json()) 如果响应体是空的或者不是合法 JSON,就会抛出 JSON 解析错误,而这个错误没被 catch 捕获。解决方案就是在 fetch 后面立刻检查 res.ok 并手动 throw。
点赞
2026-03-18 02:00