渐进式 Web 应用程序“无法脱机工作”错误

Posted

技术标签:

【中文标题】渐进式 Web 应用程序“无法脱机工作”错误【英文标题】:Progressive Web App "does not work offline" error 【发布时间】:2018-03-14 10:37:50 【问题描述】:

我按照所有可用的指南和示例编写了一个渐进式网络应用程序,但由于某种原因,当我单击 Add to homescreen 按钮时,我不断收到这个神秘的错误:

Site cannot be installed: does not work offline

我的 PWA 和示例之间的主要区别在于,我的 PWA 纯粹在域的非根路径中运行,所以我不得不在不同的地方为配置添加额外的路径,因此应用程序仅限于非根文件夹。

Google Lighthouse 网站也没有多大帮助,给出的信息非常相似。

谁能建议这个错误可能是由什么引起的?

【问题讨论】:

【参考方案1】:

所以我花了几个小时,但我最终发现有一个必需的 scope 参数,当连接到 serviceworker 时,你需要在客户端 javascript 中指定它,如果它没有在 root 上运行(@ 987654329@) 路径。

if ('serviceWorker' in navigator) 
    navigator.serviceWorker.register('sw.js?v2', 
        scope: '.' // <--- THIS BIT IS REQUIRED
    ).then(function(registration) 
        // Registration was successful
        console.log('ServiceWorker registration successful with scope: ', registration.scope);
    , function(err) 
        // registration failed :(
        console.log('ServiceWorker registration failed: ', err);
    );

您可以在此处查看正在运行的产品:

应用程序:https://stampy.me/pwgen/ 清单文件:https://stampy.me/pwgen/manifest.json ServiceWorker 文件:https://stampy.me/pwgen/sw.js 应用脚本:https://stampy.me/pwgen/script.js(滚动到底部查看 PWA 代码)

我希望我的痛苦可以为别人节省一些时间。

【讨论】:

这不是必需的。但看起来你正在将你的 PWA“限定”到该文件夹​​。所以你需要确定它的范围。您收到该错误的原因是没有针对该范围的服务工作者获取事件处理程序。这篇文章谈到了这个要求:love2dev.com/blog/… 这只是没有记录的要求(甚至在您的网站上也没有),在确定应用程序范围时,您需要在调用脚本中指定范围,将范围添加到清单不起作用,调用到网站代码中的 serviceWorker 默认为 root 范围,并忽略清单。坦率地说,这可能是 ServiceWorker 实现中的一个错误。如果我的所有网站文件都存储在相对目录中,则不需要绝对限定应用程序的范围,它只会阻碍部署到辅助位置。 @ChrisLove 实际上,我刚刚发现您可以将范围设置为 . 并且它可以工作。因此,虽然我的客户端脚本中仍然需要该参数,但它现在至少可以忽略绝对路径。 由于某种原因(stampy.me/pwgen),它现在无法离线工作。它给出了无法访问网站的错误。我在使用 Chrome 67 的 macOS 上。 stampy.me/pwgen 在 Windows10 + Chrome 73 上无法离线工作。它显示典型错误“无法访问网站”。有什么线索吗?【参考方案2】:

更新:

看起来谷歌也接受了快速破解并且警告已经返回。

因此,从 Chrome93(2021 年 8 月)开始,快速破解将不再有效:

self.addEventListener('fetch', function(event) )

解决方案“暂时”有效(因为我们永远不知道 Google 以后会添加什么要求)

我发现一篇不错的文章提供了一些解决方案,作者提供的第一个是 Network-Falling-Back-To-Cache strategy:

您的 Service Worker 将首先尝试从您的 服务器。然后当它不能那样做时——因为例如,你是 离线——从缓存中检索它(如果它存在的话)。

   self.addEventListener('fetch', function(event) 
   event.respondWith(async function() 
      try
        var res = await fetch(event.request);
        var cache = await caches.open('cache');
        cache.put(event.request.url, res.clone());
        return res;
      
      catch(error)
        return caches.match(event.request);
       
     ());
 );

您可以在文章中找到所有信息和替代解决方案:

https://javascript.plainenglish.io/your-pwa-is-going-to-break-in-august-2021-34982f329f40

我希望这对未来的访客有所帮助。

原答案:

您还需要在 service worker 文件中定义 fetch 监听器:

this.addEventListener('fetch', function (event) 
    // it can be empty if you just want to get rid of that error
);

【讨论】:

这解决了我的一切问题 @mixel 看起来 google 发现了这个 hack 并且这将不再起作用,发布关于此的更新

以上是关于渐进式 Web 应用程序“无法脱机工作”错误的主要内容,如果未能解决你的问题,请参考以下文章

IIS 子文件夹中的 Angular PWA 无法脱机工作

渐进式Web应用(PWA)

在另一个渐进式Web应用程序范围内的渐进式Web应用程序

渐进式 Web 应用程序和混合移动应用程序之间的区别

浏览器原理 26 # 渐进式网页应用(PWA):它究竟解决了Web应用的哪些问题?

渐进式web应用 (PWA)