ServiceWorker IV
Service Worker 消息传递
Client 向 Worker 发送消息
- Client 端发送消息
通过调用 ServiceWorker 实例上的 postMessage()
方法实现从 Client 端向对应的 ServiceWorker 发送消息。
1 | window.navigator.serviceWorker.controller?.postMessage('message from client') |
- Worker 端接收消息
通过监听 ServiceWorkerGlobalScope 环境的 message
事件接收消息。
1 | self.addEventListener('message', (e) => { |
Worker 向 Client 发送消息
- Worker 端发送消息
通过调用 Client 实例上的 postMessage()
方法实现从 ServiceWorker 向对应的 Client 发送消息。
1 | self.clients.get('<id>').then((client) => { |
- Client 端接收消息
通过监听 ServiceWorkerContainer 的 message
事件接收消息。
1 | window.navigator.serviceWorker.addEventListener('message', (e) => { |
Service Worker 请求代理
当主应用程序线程发出网络请求时,会在 Service Worker 的全局范围内触发 fetch
事件。
ServiceWorkerGlobalScope
接口的fetch
事件返回一个FetchEvent
事件(继承自ExtendableEvent
),在主应用程序线程发生网络请求时触发。
请求类型包括来自主线程的显式调用,还包括浏览器在页面导航后发出的加载页面和子资源(例如 JavaScript、CSS 和图像等)的隐式网络请求,甚至包括来自浏览器安装的插件产生的网络请求。可以通过 request
属性获取到请求的信息,调用 respondWith()
方法返回自定义的响应数据。
1 | self.addEventListener('fetch', (e) => { |
FetchEvent
事件的request
属性返回一个Request
实例,代表触发事件处理程序的请求对象。
FetchEvent
事件的respondWith()
方法阻止浏览器的默认请求处理机制,并允许使用自定义的响应替代,其接收一个Response
实例或者 Promise 的Response
实例。
respondWith()
方法对于给定的请求只能调用该方法一次。如果 fetch
添加了多个事件监听器,它们将按照注册的顺序被调用,直到其中一个事件监听器调用该方法。
respondWith()
方法必须同步调用,不能在异步方法中调用该方法。
若 respondWith()
未在处理程序中调用,则用户代理会自动发出原始网络请求。
FetchEvent
事件的clientId
属性返回触发 fetch 事件的 Client 的 id,可以使用Clients.get()
方法获取到对应的 Client 实例。
FetchEvent
事件的replacesClientId
属性返回若因页面导航而触发 fetch 事件的前一个 Client 的 id,否则返回一个空字符串。
FetchEvent
事件的resultingClientId
属性返回若因页面导航而触发 fetch 事件的后一个 Client 的 id,否则返回一个空字符串。
FetchEvent
事件的handled
属性返回 Promise 实例,表明 fetch 事件已被处理,并在消费请求后完成。
FetchEvent
事件的preloadResponse
属性返回若导航预加载情况下的 Promise 的 Response,否则返回 Promise 的 undefined。
示例
- https://github.com/skyclouds2001/Frontend-Learning/blob/main/next-learning/message.html
- https://github.com/skyclouds2001/Frontend-Learning/blob/main/next-learning/message.js
链接
ServiceWorker IV
https://skyclouds2001.github.io/2023/08/31/ServiceWorker-IV/