哪个 service worker 事件表明它已经控制了页面,并将拦截网络流量?
Which service worker event indicates it has controlled the page, and will intercept web traffic?
在我的网络应用中,一些网络请求必须被服务工作者拦截和修改,否则请求将失败。这对于新用户的首次访问尤为重要。我使用 clientsClaim()
来确保这一点。
因为我需要在发出请求之前确保 service worker 准备就绪,所以我尝试等待 navigator.serviceWorker.ready
:
await navigator.serviceWorker.ready;
fetch(myRequest);
但是,我发现它没有按预期工作。第一次访问的第一个请求不会被拦截。所以我试着增加一些等待时间:
await navigator.serviceWorker.ready;
await twoSeconds();
fetch(myRequest);
这可行,但它会损害用户体验,因为它会延迟第一个有意义的 UI。另一方面,我也不能确定 2 秒对每台计算机来说是否足够长。
一旦 sw 准备好拦截流量,有什么事件可以告诉我?这只是第一次访问时的问题,但理想情况下,事件会在每次重新加载时触发,因为如果我在每次访问时都简单地等待相同的事情,代码会更容易编写。
我认为您正在寻找一种承诺,当当前页面处于服务工作者的控制之下时,您可以使用它来发出信号。
这可以通过
实现
await new Promise(r => {
if (navigator.serviceWorker.controller) return r();
navigator.serviceWorker.addEventListener('controllerchange', e => r());
});
// At this point, the page will be controlled by a service worker.
此代码改编自 GitHub discussion,其中包含更多上下文。
一般来说,设计一个只有在服务工作者控制下才能工作的页面并不是很好,因为服务工作者旨在逐步增强,而不是核心要求。但是如果你有那个用例,上面的代码会有所帮助。
在我的网络应用中,一些网络请求必须被服务工作者拦截和修改,否则请求将失败。这对于新用户的首次访问尤为重要。我使用 clientsClaim()
来确保这一点。
因为我需要在发出请求之前确保 service worker 准备就绪,所以我尝试等待 navigator.serviceWorker.ready
:
await navigator.serviceWorker.ready;
fetch(myRequest);
但是,我发现它没有按预期工作。第一次访问的第一个请求不会被拦截。所以我试着增加一些等待时间:
await navigator.serviceWorker.ready;
await twoSeconds();
fetch(myRequest);
这可行,但它会损害用户体验,因为它会延迟第一个有意义的 UI。另一方面,我也不能确定 2 秒对每台计算机来说是否足够长。
一旦 sw 准备好拦截流量,有什么事件可以告诉我?这只是第一次访问时的问题,但理想情况下,事件会在每次重新加载时触发,因为如果我在每次访问时都简单地等待相同的事情,代码会更容易编写。
我认为您正在寻找一种承诺,当当前页面处于服务工作者的控制之下时,您可以使用它来发出信号。
这可以通过
实现await new Promise(r => {
if (navigator.serviceWorker.controller) return r();
navigator.serviceWorker.addEventListener('controllerchange', e => r());
});
// At this point, the page will be controlled by a service worker.
此代码改编自 GitHub discussion,其中包含更多上下文。
一般来说,设计一个只有在服务工作者控制下才能工作的页面并不是很好,因为服务工作者旨在逐步增强,而不是核心要求。但是如果你有那个用例,上面的代码会有所帮助。