如何从我的页面中调用ServiceWorker上的方法?

owe*_*ncm 11 service-worker

我在我的页面上注册了一个ServiceWorker,并希望将一些数据传递给它,以便它可以存储在IndexedDB中,以后用于网络请求(它是一个访问令牌).

使用网络请求并使用fetch在SW端捕获它们是正确的,还是有更聪明的东西?

请注意未来的读者对我有类似的想法:

在SW注册对象上设置属性,例如将self.registration.foo设置为服务工作者中的函数,并在页面中执行以下操作:

navigator.serviceWorker.getRegistration().then(function(reg) { reg.foo; })
Run Code Online (Sandbox Code Playgroud)

'TypeError:reg.foo不是函数'的结果.我认为这与ServiceWorker的生命周期有关,这意味着你无法修改它并期望将来可以访问这些修改,因此任何具有SW的接口都可能必须是postMessage样式,所以也许只使用fetch是最好的方式去......?

owe*_*ncm 20

所以事实证明你实际上无法从你的应用程序中调用SW中的方法(由于生命周期问题),所以你必须使用postMessage API来传递序列化的JSON消息(所以没有传递回调等).

您可以使用以下应用代码向控制SW发送消息:

navigator.serviceWorker.controller.postMessage({'hello': 'world'})
Run Code Online (Sandbox Code Playgroud)

结合SW代码中的以下内容:

self.addEventListener('message', function (evt) {
  console.log('postMessage received', evt.data);
})
Run Code Online (Sandbox Code Playgroud)

这导致我的SW控制台中出现以下内容:

postMessage received Object {hello: "world"}
Run Code Online (Sandbox Code Playgroud)

因此,通过传入一个消息(JS对象)来指示我想要调用的函数和参数,我的事件监听器可以接收它并在SW中调用正确的函数.要将结果返回到应用程序代码,您还需要将MessageChannel的端口传递到SW,然后通过postMessage进行响应,例如在您创建的应用程序中,并通过带有数据的MessageChannel发送:

var messageChannel = new MessageChannel();
messageChannel.port1.onmessage = function(event) {
  console.log(event.data);
};
// This sends the message data as well as transferring messageChannel.port2 to the service worker.
// The service worker can then use the transferred port to reply via postMessage(), which
// will in turn trigger the onmessage handler on messageChannel.port1.
// See https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
navigator.serviceWorker.controller.postMessage(message, [messageChannel.port2]);
Run Code Online (Sandbox Code Playgroud)

然后您可以在消息处理程序中的Service Worker中通过它进行响应:

evt.ports[0].postMessage({'hello': 'world'});
Run Code Online (Sandbox Code Playgroud)

  • 如果您需要向控制的ServiceWorker发送消息并获得某种响应,那么发出http请求通常是最简单的方法.您的ServiceWorker将在其fetch事件中看到此内容,它可以使用JSON或您想要的任何内容进行回复. (5认同)
  • 有一个全面的演示,展示了如何定义触发不同"消息"处理程序行为的不同"命令":https://github.com/GoogleChrome/samples/tree/gh-pages/service-worker/post-message (3认同)