简体   繁体   中英

How to ensure that `self.skipWaiting()` works while allowing POST requests in service worker's fetch event

I've noticed that my service worker doesn't respond to self.skipWaiting() when there are still tasks to be run.

In my service worker's fetch event, I see various Firebase polls that use HTTP POST requests.

If I handle these requests in the service worker like so:

self.addEventListener("fetch", (event) => {
  if (event.request.method === "POST") {
    return event.respondWith(new Response(null, {status: 444}))
  }

  ...
})

Then self.skipWaiting() always works as expected.

However, if I do the following:

self.addEventListener("fetch", (event) => {
  if (event.request.method === "POST") {
    return event.respondWith(fetch(event.request))
  }

  ...
})

Then self.skipWaiting() seems to have no effect. In Chrome's devtools, the new service worker still isn't active (and also clicking on the blue skipWaiting link also has no effect). Chrome devtools 屏幕截图显示新的 service worker 正在等待激活

As a result, it seems that I have to choose between ensuring that self.skipWaiting() works, and allowing Firebase's polling requests, but not both. Is there a way get self.skipWaiting() to work while still allowing Firebase's polling requests?

I don't see from your code where you're calling self.skipWaiting() , but the main thing to know about that function is that it "flips" a flag and attempts to activate the waiting service worker. I'm not sure which part of that sequence is not working as expected, and I'm also not sure if you're describing something that happens just in Chrome or in other browsers as well. If you're seeing unexpected behavior just in Chrome, filing a bug is probably your best bet.

That being said, in the interest of providing a workaround, I wanted to say that you don't have to call event.respondWith() inside of a fetch event handler at all. If all your fetch handlers complete without any of them calling fetchEvent.respondWith() , then the default browser networking behavior will be used instead. So you could restructure your fetch handler like the following, and perhaps work around the issue.

self.addEventListener("fetch", (event) => {
  if (event.request.method === 'POST') {
    return;
  }

  // Your non-POST response logic goes here.
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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