一般的なサービスワーカーのシナリオがあります。通知のクリックをキャッチして、通知の送信元のタブにフォーカスします。ただし、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は空になります。フィルタタイプ「ウィンドウ」を削除しようとしましたが、結果は同じです。クライアントが空であるため、新しいウィンドウが常に開かれます。私は何が間違っているのですか?
あなた自身のコメントの疑惑は正しいです。ページはサービスワーカーによって制御されますサービスワーカーが登録されているオリジンへのナビゲーション上。したがって、実際にServiceWorkerを初期化する元のページの読み込み自体は制御されません。そのため、新しいタブにアクセスするか、更新を行うと、ワーカーはタブを見つけるだけです。
ただし、(Jeff Posnickがコメントで指摘しているように)次のように制御されていないページを取得できます:ServiceWorkerClients.matchAll({includeUncontrolled: true, type: 'window'})
。
サービスワーカーにすぐにページを要求させてみてください。例えば。:
self.addEventListener('install', event => event.waitUntil(self.skipWaiting()));
self.addEventListener('activate', event => event.waitUntil(self.clients.claim()));
より複雑な例については、 https://serviceworke.rs/immediate-claim.html を参照してください。