如何通过 service worker 区分常规请求和 iframe 请求?

How to differ regular and iframe requests through a service worker?

所以,问题是:如何区分这些请求?也许,有一种方法可以查看请求的源元素 (iframe)?

目前,我实施的唯一解决方案是将所有本地资源移动到某个 hard-unique-named 文件夹,如果请求不是以它开头 - 它可以算作 iframe 请求。不过,我希望有更好的解决方案:)

事实证明,解决方案非常简单。首先,您需要在 Service Worker 和 iframe 激活后向其发送消息(从 iframe 发送):

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function () {
        navigator.serviceWorker.register('iframe_worker.js').then(function (registration) {
            // Registration was successful
            console.log('Iframe Service Worker registration successful with scope: ', registration.scope);
            // -> SEND MESSAGE TO GET CLIENT ID
            registration.active.postMessage({code: "get-client-id"});
        }, function (err) {
            // registration failed :(
            console.log('Service Worker registration failed: ', err);
        });
    });
}

然后,您需要处理消息并遍历 clientIds,因此您可以将主要 window 和 iframe ID 保存为变量以用于过滤。

let windowClientId = '';
let iframeClientId = '';

addEventListener('message', (event) => {
    if (event.data.code === 'get-client-id') {
        self.clients.matchAll().then(function (clients) {
            clients.forEach(function (client) {
                if (client.frameType === "top-level") {
                    windowClientId = client.id
                } else if (client.frameType === "nested") {
                    iframeClientId = client.id
                }
            });
        });
    }
});

之后,您可以根据需要过滤和处理请求:

self.addEventListener('fetch', function (event) {
    // Don't process any requests if worker/iframe are not activated fully
    if (!windowClientId || !iframeClientId) {
        return;
    }
    // Don't process main window resources
    if (event.clientId === windowClientId) {
        return;
    }
    // do smth
})