2

过去几天我一直在努力在我的 Angular 11 应用程序中加载新的 PWA 版本。开始拔头发了!

这对我来说没有发生:

“每次用户打开或刷新应用程序时,Angular Service Worker 都会通过查找 ngsw.json 清单的更新来检查应用程序的更新。如果找到更新,则会自动下载并缓存它,并将提供给下次加载应用程序时。”``` Angular - 生产中的服务工作者

我正在使用SwUpdate.checkForUpdate()效果很好的 Angular 服务,当有新版本可用时,它会检测并提示用户重新加载。该应用程序已重新加载并在新版本上,非常完美。

但是,如果我关闭手机上的应用程序,然后重新打开,它总是会回到安装 PWA 时的第一个版本:(

我已经尝试过SwUpdate.activateUpdate() window.location.reload(),更改版本号,自定义服务人员......等等等等。

唯一有效的方法是清除我在 Chrome 中的浏览数据,然后重新安装 PWA :(

我无法做任何事情来导致 PWA 缓存使用新版本进行更新。它正在获取新版本,但缓存未更新。

有人可以在这里指出我正确的方向吗?我错过了什么?

安卓 10,Chrome 89.0.4389.105

4

1 回答 1

1

主要问题是 index.html 的最长期限为 30 天。在我看来,Android 上的 Chrome 在访问pwa 缓存之前首先从标准浏览器缓存加载。

这不是在 Chrome 桌面上发生的,只是在我测试的 Android 中发生。

我通过以下方式解决了这个问题:

  1. 在 index.html 上设置一个较短的 max-age 到期(服务器端)

根据您的情况,可能不需要额外的步骤:

  1. 删除 index.htmlngsw.config.json以强制从网络加载。
  2. 自定义服务人员提供“您离线”消息(见下文)

定制服务人员,在app.module.ts

ServiceWorkerModule.register('./offline-service-worker.js', { enabled: environment.production }),

offline-service-worker.js文件:

const CACHE_NAME = 'offline';
const OFFLINE_URL = '/assets/offline-page.html';

self.addEventListener('install', (event) => {
  event.waitUntil((async () => {
    const cache = await caches.open(CACHE_NAME);
    await cache.add(new Request(OFFLINE_URL, {cache: 'reload'}));
  })());
});

self.addEventListener('activate', (event) => {
  event.waitUntil((async () => {
    if ('navigationPreload' in self.registration) {
      await self.registration.navigationPreload.enable();
    }
  })());
  self.clients.claim();
});

self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    event.respondWith((async () => {
      try {
        // First, try to use the navigation preload response if it's supported.
        const preloadResponse = await event.preloadResponse;
        if (preloadResponse) {
          return preloadResponse;
        }

        const networkResponse = await fetch(event.request);
        return networkResponse;
      } catch (error) {
        // catch is only triggered if an exception is thrown, which is likely
        // due to a network error.
        // If fetch() returns a valid HTTP response with a response code in
        // the 4xx or 5xx range, the catch() will NOT be called.
        console.log('Fetch failed; returning offline page instead.', error);

        const cache = await caches.open(CACHE_NAME);
        const cachedResponse = await cache.match(OFFLINE_URL);
        return cachedResponse;
      }
    })());
  }
});

importScripts('./ngsw-worker.js');

整个 PWA 是一件棘手的事情。但是当它起作用时很棒!

于 2021-04-07T11:24:17.580 回答