serviceworkers focus选项卡:在notificationclick上客户端为空

moa*_*rra 17 google-chrome service-worker

我有一个共同的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('/');
        }
    }));
    
});
Run Code Online (Sandbox Code Playgroud)

注册是这样的:

 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);
            });
        }
   ...
   }
Run Code Online (Sandbox Code Playgroud)

chrome:// serviceworker-internals/output表明注册和安装都很好.但是,当按下通知时,clientList为空.我试过删除过滤器类型:'window'但结果仍然相同.由于客户端为空,因此始终会打开一个新窗口.我究竟做错了什么?

Bre*_*hie 33

您自己评论中的怀疑是正确的.页面由服务工作者在导航到服务工作者注册的源时控制.因此,实际初始化服务工作者的原始页面加载本身并不受控制.这就是为什么工作人员只有在您使用新标签访问或刷新后才能找到您的标签.

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

  • 或者,[`ServiceWorkerClients.matchAll({includeUncontrolled:true,type:'window'})`](https://developer.mozilla.org/en-US/docs/Web/API/Clients/matchAll)会给你返回`Client`对象,对应于尚未控制的页面.(如果您愿意,可以随意编辑您的答案以包含该信息;我不会冒昧.) (8认同)

Mar*_*rco 5

尝试让 Service Worker 立即声明该页面。例如:

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

self.addEventListener('activate', event => event.waitUntil(self.clients.claim()));
Run Code Online (Sandbox Code Playgroud)

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