借助ngrok测试移动端Service Workers时的跨源注册错误解决方法
这个错误的核心原因很明确:你的Service Worker脚本是从localhost:3000加载的,但当前页面的源是https://abc123.ngrok.io,Service Worker的安全规则要求脚本的源必须和页面源完全一致,所以就触发了SecurityError。下面是具体的解决步骤:
第一步:启动Meteor时指定正确的ROOT_URL
Meteor默认会把localhost:3000作为应用的根URL,所有生成的资源路径(包括Service Worker脚本)都会基于这个地址。你需要在启动Meteor时,把ROOT_URL设置为ngrok提供的HTTPS地址:ROOT_URL=https://abc123.ngrok.io meteor run这样Meteor会自动用这个根URL生成Service Worker的脚本地址,保证和页面源匹配。
第二步:确保Service Worker注册代码没有硬编码localhost
如果你是手动注册Service Worker的,检查代码里有没有硬写localhost:3000的情况。最好改用相对路径或者动态获取当前页面的origin:// 推荐写法:动态获取当前页面的源来拼接SW地址 const swScriptUrl = `${window.location.origin}/sw.js`; navigator.serviceWorker.register(swScriptUrl, { scope: '/' }) .then(registration => { console.log('Service Worker注册成功:', registration); }) .catch(err => { console.error('Service Worker注册失败:', err); });这种写法能适配不同的部署环境,不管是本地localhost还是ngrok域名都能正常工作。
第三步:清除移动设备上的旧Service Worker缓存
之前在本地测试时,移动设备可能已经缓存了localhost的Service Worker,即使你改了新地址,旧的SW可能还在干扰。你可以通过以下方式清除:- 在移动设备上打开Chrome,访问
chrome://serviceworker-internals/ - 找到和
localhost:3000相关的Service Worker条目,点击Unregister - 或者直接清除应用的站点数据:Chrome设置 > 隐私和安全 > 清除浏览数据 > 勾选"缓存的图片和文件"和"Cookie及其他网站数据",然后清除
- 在移动设备上打开Chrome,访问
做完这三步,重新在移动设备上访问ngrok的地址,Service Worker应该就能正常注册了。
内容的提问来源于stack exchange,提问作者rubie

