简体   繁体   English

服务工作者本身未触发服务工作者获取事件

[英]Service Worker fetch event not triggered for service worker itself

I noticed that the fetch event of a service worker is no longer triggered when the service worker script itself is loaded in the browser.我注意到当服务工作者脚本本身加载到浏览器中时,服务工作者的 fetch 事件不再被触发。 For example, when we have a new version of a service worker, the old service workers fetch event is not triggered.例如,当我们有一个新版本的 service worker 时,旧的 service worker 的 fetch 事件不会被触发。 As consequence, the old service worker can no longer check the content of the new service worker.结果,旧的 Service Worker 无法再检查新 Service Worker 的内容。

I'm sure this was possible before and I would like to know if this is a bug or if any changes were made regarding to that.我确信这是可能的,我想知道这是否是一个错误,或者是否对此进行了任何更改。 I did not find anything in the official repository or W3C draft regarding to this change.我在官方存储库或 W3C 草案中没有找到任何关于此更改的内容。

To verify that the fetch event is not triggered I programmed a small example service worker with a version number (see code).为了验证 fetch 事件没有被触发,我编写了一个带有版本号的小型示例 service worker(参见代码)。 I have tested it the following way:我已经通过以下方式对其进行了测试:

  1. Install first version of service worker安装服务工作者的第一个版本
  2. Increase the version number to two.将版本号增加到两个。
  3. Reload the page -> So that the new sw.js file is installed in the browser.重新加载页面 -> 以便在浏览器中安装新的 sw.js 文件。
  4. Check the chrome logs -> ChromeLogs检查 chrome 日志 -> ChromeLogsChrome日志

Example 'sw.js':示例“sw.js”:

const version = 1;
console.log(`SW with v${version} executed`);

async function onFetch(event) {
    // Not triggered for sw.js
    console.log(`fetching: ${event.request.url} with v${version}`);
    return await fetch(event.request);
}

async function onInstall() {
    console.log(`sw v${version} install`);
    await self.skipWaiting();
}

async function onActivate() {
    console.log(`sw v${version} activate`);
    await self.clients.claim();
}

self.addEventListener('fetch', event => event.respondWith(onFetch(event)));
self.addEventListener('install', event => event.waitUntil(onInstall()));
self.addEventListener('activate', event => event.waitUntil(onActivate()));

As we can see from the logs, the sw.js file was not fetched, but another fiel (test.js) was fetched before the new service worker was installed.从日志中我们可以看到,sw.js 文件没有被获取,但是在新的 service worker 安装之前,另一个文件(test.js)被获取了。 I included the test.js javascript file to see if the service worker was fetching anything.我包含了 test.js javascript 文件,以查看服务人员是否在获取任何内容。 So from this test we can see that the fetch event is not triggered for service worker script itself.所以从这个测试中我们可以看到,服务工作者脚本本身没有触发 fetch 事件。

What I would like to know is, is there any way to fetch the new service worker javascript file before it gets loaded within the old service worker?我想知道的是,有没有办法在新的服务工作者 javascript 文件被加载到旧的服务工作者中之前获取它? Are there any other events that make this possible?是否有任何其他事件使这成为可能? I do not need to intercept the script from executing or replacing the old service worker.我不需要拦截脚本来执行或替换旧的服务工作者。 I just want to check the content of the new service worker before it is loaded.我只想在加载新服务人员之前检查它的内容。

EDIT :编辑

<html>
    <body>
        <h1>hello</h1>
        <script src="test.js"></script>
        <button onclick="runFetch()">fetch</button>
        <h2 id="swVersion"></h2>
        <script>
            navigator.serviceWorker.register('/sw.js'); // First Installation
            fetch('/sw.js'); // Triggers fetch event, but is independent from update routine.
            async function runFetch() {
                console.log(await fetch('/sw.js'));
            }
        </script>
    </body>
</html>

The service worker update check that is initiated by the browser always bypasses all service worker fetch handlers.由浏览器发起的服务工作者更新检查总是绕过所有服务工作者fetch处理程序。 It might end up being fulfilled by the HTTP Cache, although all modern browsers default to also bypassing the HTTP Cache and going straight to the network.它可能最终由 HTTP 缓存实现,尽管所有现代浏览器默认也绕过 HTTP 缓存并直接进入网络。

I'm fairly confident that no browser has ever triggered the previous service worker's fetch event handler when performing the service worker update check, as that's explicitly forbidden by the service worker specification (the service-workers mode of the update request is required to be set to 'none' ).我相当有信心在执行服务工作人员更新检查时没有浏览器触发过以前的服务工作人员的fetch事件处理程序,因为服务工作人员规范明确禁止这样做(需要设置更新请求的服务工作人员模式'none' )。 This helps developers avoid scenarios in which an old service worker could get "stuck" if it did something incorrect when processing the fetch event for a new service worker.这有助于开发人员避免在处理新 Service Worker 的fetch事件时旧 Service Worker 可能会“卡住”的情况。

I'm not sure why you might have thought otherwise—perhaps you are thinking about the HTTP Cache interaction.我不知道您为什么会有其他想法——也许您正在考虑 HTTP 缓存交互。 Or perhaps you're thinking about a scenario in which a web app explicitly calls fetch('service-worker.js') to check to see if a service worker exists at a given URL, which will trigger the fetch handler of the service worker in control of a given page.或者您可能正在考虑 web 应用程序显式调用fetch('service-worker.js')以检查给定 URL 中是否存在服务工作者,这触发服务工作者的fetch处理程序控制给定的页面。 But calling fetch('service-worker.js') is very different from the service worker update check.但是调用fetch('service-worker.js')与 service worker 更新检查有很大不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM