fetch断网时直接reject并抛TypeError,必须用catch或try/catch捕获;response.ok和status无效,因无response对象。

当网络断开时,fetch 本身**不会直接抛出 TypeError**,但会在请求无法建立连接(如 DNS 失败、服务器不可达、网络完全中断)时,返回一个被拒绝的 Promise,并以 TypeError 为 rejection 原因。关键在于:这个错误**必须用 catch 捕获,不能靠 if (!response.ok) 检测**,因为请求根本没发出去,压根没有 response 对象。
为什么 fetch 会抛 TypeError?
根据浏览器规范,当 fetch 因网络层问题(如无网络、目标主机不可达、CORS 预检失败等)无法发起请求时,Promise 会立即 reject,并附带一个 TypeError 实例(message 通常含 "Failed to fetch" 或 "NetworkError")。这不是业务错误,而是底层连接失败。
正确捕获断网导致的 TypeError
必须在 fetch() 调用后链式使用 .catch(),或在 async/await 中用 try/catch:
- 使用 async/await(推荐):
try {
const res = await fetch('/api/data');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log(data);
} catch (err) {
if (err instanceof TypeError && err.message.includes('fetch')) {
console.error('网络异常:请检查网络连接');
} else {
console.error('其他错误:', err);
}
}
立即学习“Java免费学习笔记(深入)”;
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 使用 .then().catch():
fetch('/api/data')
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => {
if (err instanceof TypeError) {
console.error('断网或请求未发出:', err.message);
}
});
注意:response.ok 和 status 无法捕获断网
response.ok 和 response.status 只在 fetch 成功拿到响应后才可用。一旦网络中断,fetch() 的 Promise 直接 reject,后续 .then() 根本不执行,所以以下写法无效:
fetch('/api/data')
.then(res => {
// 这里永远不会运行 —— 断网时 res 根本不存在
if (!res.ok) { /* ... */ }
})
增强判断:区分断网和其他 TypeError
并非所有 TypeError 都是断网,比如传入非法 URL 也会抛 TypeError。可结合 message 和上下文判断:
- 常见断网相关 message:
"Failed to fetch"、"NetworkError when attempting to fetch resource"、"Load failed"(Chrome)、"TypeError: Network request failed"(React Native) - 简单健壮判断方式:
err instanceof TypeError && /failed|network|load/i.test(err.message) - 更稳妥做法:配合
navigator.onLine做辅助提示(注意它只是参考,不绝对准确)

















