Ionic Capacitor3迁移自Cordova后离线断网登录报错弹窗不显示
问题描述
关闭WiFi后点击登录页面的提交按钮触发异常:已预先实现网络状态检测逻辑,预期网络断开时弹出告警提示,但实际抛出系列报错,预设的告警弹窗未正常展示。
完整报错信息如下:
1. zone.js:2680 POST net::ERR_INTERNET_DISCONNECTED Button.handleClick @ ion-button_2.entry.js:165 zone.js:1061 Unhandled Promise rejection: Cannot read properties of undefined (reading 'isProxied') ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot read properties of undefined (reading 'isProxied') NgForm_submit_HostBindingHandler @ forms.js:4139 executeListenerWithErrorHandling @ core.js:15327 wrapListenerIn_markDirtyAndPreventDefault @ core.js:15365 (anonymous) @ platform-browser.js:561 invokeTask @ zone.js:406 onInvokeTask @ core.js:28679 invokeTask @ zone.js:405 runTask @ zone.js:178 invokeTask @ zone.js:487 invokeTask @ zone.js:1648 globalCallback @ zone.js:1679 globalZoneAwareCallback @ zone.js:1712 Button.handleClick @ ion-button_2.entry.js:165 index-b3eecb14.js:2015 ChunkLoadError: Loading chunk node_modules_ionic_core_dist_esm_ion-alert_entry_js failed. (error: http://172.25.20.65:8100/node_modules_ionic_core_dist_esm_ion-alert_entry_js.js) LoginPage_Template_form_ngSubmit_14_listener @ template.html:22 executeListenerWithErrorHandling @ core.js:15327 wrapListenerIn_markDirtyAndPreventDefault @ core.js:15365 __tryOrUnsub @ Subscriber.js:183 next @ Subscriber.js:122 _next @ Subscriber.js:72 next @ Subscriber.js:49 next @ Subject.js:39 emit @ core.js:25955 onSubmit @ forms.js:4106 NgForm_submit_HostBindingHandler @ forms.js:4139 executeListenerWithErrorHandling @ core.js:15327 wrapListenerIn_markDirtyAndPreventDefault @ core.js:15365 Show 54 more frames zone.js:1061 Unhandled Promise rejection: Cannot read properties of undefined (reading 'isProxied') ; Zone: <root> ; Task: Promise.then ; Value: TypeError: Cannot read properties of undefined (reading 'isProxied') at index-b3eecb14.js:1702:23 at Generator.next (<anonymous>) at asyncGeneratorStep (asyncToGenerator.js:3:1) at _next (asyncToGenerator.js:25:1) at _ZoneDelegate.invoke (zone.js:372:1) at Zone.run (zone.js:134:1) at zone.js:1275:1 at _ZoneDelegate.invokeTask (zone.js:406:1) at Zone.runTask (zone.js:178:1) at drainMicroTaskQueue (zone.js:585:1) TypeError: Cannot read properties of undefined (reading 'isProxied') at http://172.25.20.65:8100/vendor.js:113156:19 at Generator.next (<anonymous>) at asyncGeneratorStep (http://172.25.20.65:8100/vendor.js:158781:24) at _next (http://172.25.20.65:8100/vendor.js:158803:9) at _ZoneDelegate.invoke (http://172.25.20.65:8100/polyfills.js:9841:26) at Zone.run (http://172.25.20.65:8100/polyfills.js:9603:43) at http://172.25.20.65:8100/polyfills.js:10744:36 at _ZoneDelegate.invokeTask (http://172.25.20.65:8100/polyfills.js:9875:31) at Zone.runTask (http://172.25.20.65:8100/polyfills.js:9647:47) at drainMicroTaskQueue (http://172.25.20.65:8100/polyfills.js:10054:35)
该异常出现于项目从Cordova迁移至Capacitor之后。
根因分析
- 触发链路:断网状态下点击登录,表单提交先发起登录POST请求,直接抛出
net::ERR_INTERNET_DISCONNECTED网络错误,逻辑进入预设的断网告警分支,尝试调用ion-alert组件弹窗。 - Chunk加载失败:Capacitor的资源加载逻辑和Cordova存在差异,Ionic默认对
ion-alert这类交互组件做按需懒加载,断网状态下无法从当前运行的服务地址拉取对应组件的chunk包,直接抛出ChunkLoadError。 - isProxied报错:
ion-alert组件chunk加载失败后,Ionic和Capacitor通信的组件代理层拿不到有效组件实例,访问实例上的isProxied属性时触发类型错误,抛出未捕获的Promise异常,直接打断所有后续容错逻辑。 - 网络检测未生效原因:原有网络检测逻辑没有放在表单提交的最前置位置,点击提交后优先发起了接口请求,等请求报错后才走到告警分支,此时已经因为断网无法加载弹窗资源,双重异常导致预期的告警完全无法展示。
修复步骤
- 前置网络校验逻辑
将网络状态检测移到登录表单提交逻辑的最入口,检测到断网时直接终止后续请求流程,不发起登录接口请求,直接触发提示。参考实现:async onFormSubmit() { // 最优先做网络状态校验 const networkStatus = await Network.getStatus(); if (!networkStatus.connected) { this.showOfflineTip(); return; } // 后续正常登录请求逻辑 } - 配置Ionic组件预加载
在应用根模块的Ionic配置中开启核心组件预加载,将Alert、Toast、Loading等高频使用的交互组件提前打包进本地资源,避免断网时动态拉取chunk失败。参考配置:// app.module.ts import { IonicModule } from '@ionic/angular'; @NgModule({ imports: [ IonicModule.forRoot({ preloadModules: true // 开启模块预加载 }) ] }) export class AppModule {} - 增加弹窗加载容错
封装全局提示方法时增加异常捕获,若Ionic组件弹窗加载失败,自动降级为Capacitor原生Dialog弹窗,保证极端断网场景下提示可以正常展示,同时避免抛出未捕获异常。参考实现:async showOfflineTip() { try { const alert = await this.alertController.create({ header: '网络异常', message: '当前网络已断开,请检查连接后重试', buttons: ['确定'] }); await alert.present(); } catch (err) { // 降级调用原生弹窗 await Dialog.alert({ title: '网络异常', message: '当前网络已断开,请检查连接后重试' }); } }
内容的提问来源于stack exchange,提问作者Thang
相关产品推荐
相关产品推荐

