如何解决 Service Worker 导航“此 Service Worker 不是客户端的活动 Service Worker”错误?

nul*_*ele 6 javascript vue.js service-worker firebase-cloud-messaging quasar-framework

我为我的 quasar pwa 创建了一个服务工作人员来管理 fcm Web 后台通知。目的是管理前台和后台通知的点击并将用户重定向到我的 PWA 的特定页面。

因此,当我收到通知时,我有两种情况:

前台通知

  • 1a) 浏览器聚焦/最大化 + 用户已经在 PWA 选项卡上 + PWA 位于右侧页面 -> 无需执行任何操作
  • 1b) 浏览器聚焦/最大化 + 用户已经位于 pwa 选项卡上 + pwa 位于另一个页面上 -> 我必须重定向到特定的 pwa 页面

后台通知

  • 2a) 浏览器未聚焦或最小化,或者用户不在 PWA 选项卡上 + PWA 位于右侧页面 -> 我必须聚焦/最大化浏览器或聚焦 PWA 选项卡,然后无事可做
  • 2b) 浏览器未聚焦或最小化,或者用户不在 PWA 选项卡上 + PWA 在另一个页面上 -> 我必须聚焦/最大化浏览器或聚焦 PWA 选项卡,然后重定向到特定的 PWA 页面

1a、1b 和 2a 中一切正常。对于 2b,我收到这个奇怪的错误“此服务工作线程不是客户端的活动服务工作线程”。

我在服务工作人员中有以下代码来管理后台通知单击时的重定向。我在navigate()方法上收到错误。

self.addEventListener('notificationclick', function(event) {
    console.log('notificationclick', event);
    event.notification.close();

    let route = event.notification.data.route ? JSON.parse(event.notification.data.route) : null;
    if(route && route.params && route.params.token) {
      const domain = route.domain;
      const path = '/#/' + route.name + '/' + route.params.token;
      const fullUrl = domain + path

      event.waitUntil(clients.claim().then(() => {
          return clients.matchAll({
            type: 'window',
            includeUncontrolled: true
          })
          .then(clients => clients.filter(client => client.url.indexOf(domain) !== -1))
            .then(matchingClients => {
              if (matchingClients[0]) {
                return matchingClients[0].focus().then(function (client) {
                  client.navigate(path)
                    .then(client => {
                    }).catch(function (e) {
                    console.log(e); --> here I get the error
                  });
                }).catch(function (e) {
                  console.log(e);
                });
              }

              return clients.openWindow(fullUrl);
            })
          })
      );
    }
  });
Run Code Online (Sandbox Code Playgroud)

我在网上搜索了这个错误,但没有找到任何参考资料,所以我不明白这个错误,也无法解决它。有人可以帮忙吗?谢谢

Cor*_*ius 6

无论我尝试什么,我都无法让它工作 client.navigate(path)......经过几个小时的搜索并在 GitHub、MDN 文档等中深入研究后,我最终使用了该client.postMessage()界面。

在上面的代码中替换client.navigate(path)为以下内容:

client.postMessage({
  action: 'redirect-from-notificationclick',
  url: path,
})
Run Code Online (Sandbox Code Playgroud)

然后在您的应用程序代码中收听此消息:

// Listen to service worker messages sent via postMessage()
navigator.serviceWorker.addEventListener('message', (event) => {
  if (!event.data.action) {
    return
  }

  switch (event.data.action) {
    case 'redirect-from-notificationclick':
      window.location.href = event.data.url
      break
    // no default
  }
})
Run Code Online (Sandbox Code Playgroud)