如何在窗口内代码中获取当前窗口对应的WindowClient id?
如何在窗口代码中获取对应Service Worker的WindowClient ID
目前浏览器没有提供让窗口代码直接获取自身对应Service Worker中WindowClient ID的原生API,但可以通过窗口与Service Worker双向通信的方式实现。
实现步骤
- 窗口端发送请求消息,告知Service Worker需要获取当前窗口的ID
- Service Worker接收消息后,通过
event.source.id直接获取发送消息的窗口对应的Client ID(无需遍历clients.matchAll),再将ID返回给窗口 - 窗口端监听Service Worker的响应消息,拿到对应的ID
代码示例
窗口端代码
// 注册Service Worker(若未注册) if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(async registration => { // 等待Service Worker激活 await navigator.serviceWorker.ready; // 发送消息请求ID navigator.serviceWorker.controller.postMessage({type: 'GET_CLIENT_ID'}); }); } // 监听Service Worker返回的消息 navigator.serviceWorker.addEventListener('message', event => { if (event.data.type === 'CLIENT_ID') { console.log('当前窗口对应的WindowClient ID:', event.data.id); // 这里可以使用拿到的ID做后续操作 } });
Service Worker端代码(sw.js)
self.addEventListener('message', event => { if (event.data.type === 'GET_CLIENT_ID') { // event.source就是发送消息的WindowClient实例,直接取其id event.source.postMessage({ type: 'CLIENT_ID', id: event.source.id }); } });
补充说明
- 确保Service Worker已成功注册并激活,否则
navigator.serviceWorker.controller可能为null - 如果窗口是未被Service Worker控制的(即
includeUncontrolled: true包含的窗口),需要先让Service Worker控制该窗口,可以通过navigator.serviceWorker.register后调用registration.waiting.postMessage({type: 'SKIP_WAITING'}),并在Service Worker中监听message事件调用self.skipWaiting()来激活控制
内容的提问来源于stack exchange,提问作者Mikael Lindqvist
相关产品推荐
相关产品推荐

