PWA如何实现离线运行?本地调试ServiceWorker注册报错如何解决
结论
PWA完全可以实现离线运行,无需借助Electron、安卓或iOS应用。
问题原因
- 直接用
file://协议打开本地HTML文件时,浏览器会将源标记为null,Service Worker规范明确禁止在非HTTP/HTTPS协议下注册,因此会触发你遇到的协议不支持报错,该限制无绕过方案。 - 本地用LiveServer运行时仅开服务器才能用,大概率是两个原因:一是你当前的Service Worker仅缓存了
index.html,未包含所有需要离线运行的CSS、JS、图片等静态资源;二是首次访问时未等Service Worker完成资源缓存就关闭了服务器,导致本地没有可用的离线缓存。
解决步骤
补全PWA基础配置
你需要新增manifest.json文件,放在项目根目录,示例配置如下:{ "name": "你的PWA名称", "short_name": "短名称", "start_url": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#000000", "icons": [ { "src": "icon.png", "sizes": "192x192", "type": "image/png" } ] }同时在
index.html的head标签中引入该文件:<link rel="manifest" href="/manifest.json">修正Service Worker缓存逻辑
你需要将所有离线需要用到的静态资源都加入缓存列表,同时给缓存加版本号方便后续更新,修改后代码示例:const CACHE_NAME = 'sw-cache-v1'; const OFFLINE_RESOURCES = [ '/', '/index.html', // 在这里添加所有需要离线的资源路径,比如css、js、图片等 '/style.css', '/app.js', '/icon.png' ]; self.addEventListener("install", function (event) { event.waitUntil( caches.open(CACHE_NAME).then(function (cache) { return cache.addAll(OFFLINE_RESOURCES); }) ); self.skipWaiting(); }); self.addEventListener("activate", function(event) { // 激活时清理旧版本缓存 event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.filter(function(cacheName) { return cacheName !== CACHE_NAME; }).map(function(cacheName) { return caches.delete(cacheName); }) ); }) ); }); self.addEventListener("fetch", function (event) { event.respondWith( caches.match(event.request).then(function (response) { return response || fetch(event.request); }) ); });本地验证离线功能
启动LiveServer后首次访问http://127.0.0.1:5500,等待页面完全加载、Service Worker安装完成后,关闭LiveServer,再次访问地址或者打开已安装的PWA,即可正常离线运行。发布给用户使用
将项目部署到任意支持HTTPS的服务器即可,用户首次访问时保持联网状态完成资源缓存,后续即可离线使用。
内容的提问来源于stack exchange,提问作者rivercity
相关产品推荐
相关产品推荐

