javascript - Workbox - 后台同步 - 离线发布 - 当浏览器重新在线时重播事件不会被触发

标签 javascript service-worker

我正在使用 workbox v4.3.1 为 Web 应用程序的用户提供离线功能。

虽然在 Chrome 中一切都像您期望的 PWA 一样完美地工作(即一切都缓存在本地,但应用程序的所有更新都被捕获在 IndexedDB 中,并在应用程序重新联机时同步回服务器。

然而,对我而言,主要用例是为 iOS Safari 提供支持并作为 PWA。

虽然所有页面都使用 Safari 中的 Service Worker 在本地缓存,并且所有离线更新也都捕获在索引数据库中,如下所示,

enter image description here

但是,当连接恢复在线时,浏览器(在本例中为 Safari)不会触发同步事件。虽然 Safari 本身不支持后台同步,但我希望当我刷新页面时,如果 SW 初始化发现一些数据要刷新到索引数据库中的服务器,它应该手动触发同步事件。

但这并没有发生,我尝试手动收听“消息” - “replayRequests”,然后重播请求 - 但效果不佳。

如有任何帮助,我们将不胜感激。这是供引用的服务 worker 代码。

// If we're not in the context of a Web Worker, then don't do anything
if ("function" === typeof importScripts) {
  importScripts(
    "https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"
  );

  //Plugins
  // Background Sync Plugin.
  const bgSyncPlugin = new workbox.backgroundSync.Plugin("offlineSyncQueue", {
    maxRetentionTime: 24 * 60
  });

  // Alternate method for creating a queue and managing the events ourselves.
  const queue = new workbox.backgroundSync.Queue("offlineSyncQueue");
  workbox.routing.registerRoute(
    matchCb,
    workbox.strategies.networkOnly({
      plugins: [
        {
          fetchDidFail: async ({ request }) => {
            await queue.addRequest(request);
          }
        }
      ]
    }),
    "POST"
  );
  // CacheKeyControlPlugin
  const myCacheKeyPlugin = {
    cacheKeyWillBeUsed: async ({ request, mode }) => {
      normalizedUrl = removeTimeParam(request.url);
      return new Request(normalizedUrl);
    }
  };

  if (workbox) {
    console.info("SW - Workbox is available and successfully installed");
  } else {
    console.info("SW - Workbox unavailable");
  }

  //Intercept all api requests
  var matchCb = ({ url, event }) => {
    // Filter out the presence api calls
    return url.pathname.indexOf("somethingidontwanttocache") == -1;
  };

  function removeTimeParam(urlString) {
    let url = new URL(urlString);
    url.searchParams.delete("time");
    return url.toString();
  }
  /* //Pre cache a page and see if it works offline - Temp code
  workbox.precaching.precache(getPageAPIRequestURLs(), {
    cleanUrls: false
  }); */
  workbox.routing.registerRoute(
    matchCb,
    new workbox.strategies.CacheFirst({
      cacheName: "application-cache",
      plugins: [myCacheKeyPlugin]
    })
  );

  self.addEventListener("message", event => {
    if (event.data === "replayRequests") {
      queue.replayRequests();
    }
  });
}

最佳答案

workbox-background-sync 在服务工作进程启动时通过重放排队请求来模拟缺乏 native 支持的浏览器中的后台同步功能。 Service Worker 进程应该是轻量级和短暂的,并且会在一段时间内没有任何事件时被主动终止,然后再次启动以响应更多事件。

重新加载网页可能会导致服务 worker 进程启动,假设它之前已停止。但是,如果 service worker 仍在运行,则重新加载页面只会导致在现有进程上触发 fetch 事件。

service worker 进程在被杀死之前可以保持空闲的时间间隔取决于浏览器。

Chrome 的 DevTools 提供了一种检查服务 worker 状态并按需启动/停止它的方法,但我认为 Safari 的 DevTools 不提供该功能。如果您想保证服务 worker 已停止然后再次启动它,我会退出 Safari,重新打开它,然后导航回您的 Web 应用程序。

关于javascript - Workbox - 后台同步 - 离线发布 - 当浏览器重新在线时重播事件不会被触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57863098/

相关文章:

javascript - Angular 2 的组件装饰器中的指令属性发生了什么变化?

javascript - 将类应用于动态添加的行

javascript - Node.js TCP 服务器传入缓冲区

javascript - AngularJS + typescript : Write a Service Worker in Typescript

firebase - FCM 通知单击始终在新选项卡中打开(网络应用程序 Polymer)

javascript - 突出显示表行中项目之间的差异

javascript - 尽管加载但未找到 Python Selenium : WebDriverWait, 元素

javascript - serviceworker 是否可以将 header 添加到 url 请求

service-worker - 如何在用户脚本中使用服务 worker

caching - 覆盖 PWA Service Worker 中的浏览器缓存