serviceworkers 焦点选项卡:客户在通知点击时为空

serviceworkers focus tab: clients is empty on notificationclick

我有一个常见的 serviceworker escenario,我想在其中捕获通知点击并将焦点放在通知来自的选项卡上。但是,clients 变量始终为空,其长度为 0

console.log("sw startup");
self.addEventListener('install', function (event) {
    console.log("SW installed");
});

self.addEventListener('activate', function (event) {
    console.log("SW activated");
});
self.addEventListener("notificationclick", function (e) {
    // Android doesn't automatically close notifications on click 
    console.log(e);
    e.notification.close();
  
    // Focus tab if open
    e.waitUntil(clients.matchAll({
        type: 'window'
    }).then(function (clientList) {
        console.log("clients:" + clientList.length);
        for (var i = 0; i < clientList.length; ++i) {
            var client = clientList[i];
            if (client.url === '/' && 'focus' in client) {
                return client.focus();
            }
        }

        if (clients.openWindow) {
            return clients.openWindow('/');
        }
    }));
    
});

注册是这个:

 this.doNotify = function (notification) {      
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('sw.js').then(function (reg) {
               
                requestCreateNotification(notification, reg);
            }, function (err) {
                console.log('sw reg error:' + err);
            });
        }
   ...
   }

chrome://serviceworker-internals/ 输出显示注册安装没问题。但是,推送通知时,clientList 为空。我尝试删除过滤器类型:'window',但结果仍然相同。由于客户端为空,因此总是会打开一个新的 window。我做错了什么?

你自己评论中的怀疑是正确的。页面由服务工作者 控制,导航到服务工作者注册的来源 。所以实际初始化 service worker 的原始页面加载本身是不受控制的。这就是为什么工作人员只会在您访问新标签页或进行刷新后才能找到您的标签页。

但是(正如 Jeff Posnick 在评论中指出的那样)您可以获得不受控制的页面,如下所示:ServiceWorkerClients.matchAll({includeUncontrolled: true, type: 'window'}).

尝试让 Service Worker 立即认领页面。 例如:

self.addEventListener('install', event => event.waitUntil(self.skipWaiting()));

self.addEventListener('activate', event => event.waitUntil(self.clients.claim()));

有关更复杂的示例,请参阅 https://serviceworke.rs/immediate-claim.html