fetch网络断开会返回被拒绝的promise,必须用catch捕获;需配合超时控制(abortcontroller)和navigator.online辅助判断,但后者不可靠;最终应统一在catch中提示并支持重试。

网络断开属于 fetch 的底层连接失败,不会进入 then,但也不会直接抛出传统错误(如 404、500 那类 HTTP 错误),而是让 fetch() 返回一个被拒绝的 Promise —— 所以必须用 catch 捕获,且要配合超时控制和连接状态判断才更可靠。
用 catch 捕获 fetch 被拒绝的 Promise
fetch 在 DNS 失败、服务器无响应、网络完全中断等场景下,会立即或稍后 reject,而不是 resolve 后返回 error status。这意味着:
- 不能只靠检查
response.ok或response.status—— 那些是请求发出去并收到响应后才存在的; - 必须用
.catch()或try/catch(配合await)来捕获连接层失败。
示例:
fetch('/api/data')
.then(res => {
// 只有网络通畅、服务有响应才会到这里
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => {
// ✅ 这里能捕获:网络断开、跨域失败、DNS 解析失败、AbortError 等
console.error('请求失败(可能是网络断开):', err.message);
});
主动添加超时,避免 fetch 无限挂起
原生 fetch 不支持超时,网络卡住(如 WiFi 信号弱但未断开)时可能长时间 pending,用户无感知。需手动封装超时逻辑:
- 用
AbortController配合setTimeout主动中止请求; - 中止后
fetch抛出AbortError,可在catch中识别为“疑似断网”或“响应过慢”。
简易超时封装:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
function fetchWithTimeout(url, options = {}, timeout = 8000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
return fetch(url, { ...options, signal: controller.signal })
.finally(() => clearTimeout(id));
}
// 使用
fetchWithTimeout('/api/data')
.catch(err => {
if (err.name === 'AbortError') {
console.warn('请求超时,可能网络异常');
} else {
console.error('网络连接失败:', err.message);
}
});
结合 navigator.onLine 辅助判断(仅作参考)
navigator.onLine 是浏览器提供的粗略网络状态指示,但它不可靠:
- 返回
false时,基本可确认离线; - 返回
true并不保证能连上目标服务器(比如内网正常但外网断开、代理故障等)。
建议仅用于快速提示,不替代 fetch.catch:
if (!navigator.onLine) {
console.warn('浏览器检测到离线,请检查网络');
// 可提前给出 UI 提示,但依然要发起 fetch 并 catch,因为 onLine 可能滞后或误报
}
服务端兜底 + 用户反馈更实用
纯前端无法 100% 区分“断网”和“服务不可达”,实际开发中更推荐:
- 统一在
catch中展示「网络异常,请检查连接」类提示; - 对关键操作(如提交表单)增加重试按钮;
- 记录错误日志(如
err.name、err.message)帮助定位真实原因。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










