Chrome新版本下pushManager.subscribe()随机触发AbortError问题咨询
排查方向
- Chrome版本特性适配问题:Chrome 110及以上版本对推送服务的网络请求新增了更严格的超时、跨域限制,部分用户因网络环境不稳定(如运营商劫持、内网限制、境外服务连通异常)无法连接Chrome内置的FCM推送服务时,就会触发该AbortError,这是随机报错的核心诱因之一。
- Service Worker注册时序问题:现有代码中
navigator.serviceWorker.register和navigator.serviceWorker.ready是并行执行的,没有等待注册流程完成,部分场景下Service Worker还未完成初始化就调用pushManager相关接口,会触发请求中断报错。 - 权限状态不一致问题:通过
navigator.permissions.query拿到的通知权限为granted时,可能存在浏览器推送服务被系统层面禁用的情况(如Windows/macOS系统通知权限关闭、Chrome后台数据刷新权限被禁用),此时调用subscribe接口会偶发失败。 - 应用公钥格式问题:如果applicationServerKey直接传入Base64字符串,未转换为标准Uint8Array格式,Chrome部分版本解析密钥时会出现偶发失败。
解决方案
- 修正Service Worker注册时序,先等待注册完成再执行后续逻辑,同时增加重试机制解决网络波动导致的偶发失败:
// 密钥格式转换工具函数 function urlBase64ToUint8Array(base64String) { const padding = '='.repeat((4 - base64String.length % 4) % 4); const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/'); const rawData = window.atob(base64); const outputArray = new Uint8Array(rawData.length); for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; } // 修正后的注册&订阅逻辑 try { // 等待Service Worker注册完成 const registration = await navigator.serviceWorker.register('/serviceworker.js', { scope: '/myScope' }); await navigator.serviceWorker.ready; // 前置校验pushManager可用性 if (!registration.pushManager) { console.log('当前环境不支持推送服务'); return; } const subscribeOptions = { userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array('myKey') }; // 失败重试逻辑,最多重试3次,间隔2s let retryCount = 0; let pushSubscription = null; while (retryCount < 3) { try { pushSubscription = await registration.pushManager.subscribe(subscribeOptions); break; } catch (err) { retryCount++; if (retryCount >= 3 || err.name !== 'AbortError') throw err; await new Promise(resolve => setTimeout(resolve, 2000)); } } // 推送订阅信息上报服务端逻辑 } catch (err) { if (err.name === 'AbortError') { // 该类错误为用户侧环境限制导致,直接降级,不影响主流程 console.log('推送服务不可用,已降级'); return; } console.error('推送订阅失败', err); }
- 针对面向国内用户的应用,Chrome内置推送依赖Google服务,国内无Google Play环境的设备本身无法使用推送功能,可以针对国内用户直接关闭推送逻辑,避免上报无意义错误。
- 对AbortError类错误做单独过滤,这类错误均为用户侧环境限制导致,无需作为业务异常处理,直接标记为用户不支持推送即可。
内容的提问来源于stack exchange,提问作者jp1987
相关产品推荐
相关产品推荐

