唯一可靠方式是 uni.onnetworkstatuschange,需在 onshow 中重注册、防抖比对、权限校验及业务层二次验证;uni.getnetworktype 仅为启动快照,无法实时响应网络变化。

uni-app 检测网络连接状态变化,唯一可靠方式是用 uni.onNetworkStatusChange,但它不是“注册一次就一劳永逸”,必须配合 onShow 重注册、防抖比对、权限校验和业务层二次验证,否则真机上大概率静默失效。
为什么 uni.getNetworkType 不能代替实时监听
它只是快照:App 启动时调一次,返回 res.networkType(如 'wifi' 或 'none'),但之后用户切 WiFi、开飞行模式、进电梯,这个值完全不会变。安卓冷启动可能直接返回 'unknown';iOS 在无网时回调延迟 2–3 秒,页面会白屏卡住。它适合初始化兜底,不能做状态响应。
uni.onNetworkStatusChange 必须在 onShow 中注册
这个 API 在 App 切后台后会被系统强制释放,iOS/Android 都如此,不是 bug。只在 main.js 或 App.vue.created 里注册一次,切到桌面再回来就彻底收不到回调。
- 把注册逻辑统一写进
App.vue的onShow钩子中,每次前台可见都重装 - 注册前先调一次
uni.getNetworkType,拿到初始isConnected值,避免首次回调延迟导致 UI stale - 务必在
onHide中调用uni.offNetworkStatusChange,否则可能内存泄漏或重复触发
防抖 + 状态比对才能避免地铁式弹窗
隧道穿行、企业内网 DHCP 延迟等场景会让 res.isConnected 在 true/false 间高频跳变。直接每次触发都 uni.showToast,用户会看到“已断开→已恢复→已断开…”连环闪现。
- 用全局变量(如
window.__lastConnected)缓存上一次状态,只在res.isConnected === false && window.__lastConnected === true时才触发提示 - 加 1.5 秒防抖:用
setTimeout缓存判断,连续两次false才认定为真实断网 - 限制单日最多弹 3 次,靠
uni.getStorageSync('offline_count')+ 时间戳控制 - 只在当前活跃页(
getCurrentPages().pop()?.route === 'pages/home/index')才执行 UI 提示
isConnected: true 不等于业务可用
系统返回 isConnected: true 和 networkType: 'wifi',只代表链路层通了——比如连上了没配 DNS 的热点、公司防火墙拦截、运营商 NAT 失效,都会导致“看着有网,实际打不开接口”。
- 关键操作(如打卡、提交、同步)前,必须发一个轻量请求(如
GET /health)验证服务可达性 - 别把
uni.request的失败直接等同于断网:可能是 token 过期、URL 错误、服务端 503,得结合 HTTP 状态码和超时判断 - iOS 真机下若
manifest.json没填NSLocationWhenInUseUsageDescription或用户拒了定位权限,networkType永远是'unknown'或'none',监听形同虚设











