ServiceWorker
Service Worker
一、概述
Service Worker 是一种在浏览器后台运行的脚本,与网页(主线程)完全分离。运行在独立线程中,不直接操作 DOM,而是通过事件机制与页面进行通信。它要求在 HTTPS 环境下运行(或 localhost 环境下开发)。
其主要作用包括:
拦截网络请求:通过监听 fetch
事件,Service Worker 能够捕获页面的网络请求,返回缓存内容或自定义响应。
离线支持:通过缓存静态资源,实现网络断线时依然可用的离线体验。
后台任务:支持后台同步(Background Sync)和推送通知(Push Notifications),即使页面关闭也可处理一些任务。
二、Service Worker 注册
在使用 Service Worker 之前,需要在网页的主线程中注册它。
通常的注册代码如下:
1 |
|
说明:
检查
serviceWorker
是否存在于navigator
对象中,确保浏览器支持该特性。监听
load
事件确保页面资源加载完毕后再注册。registration.scope
表示 Service Worker 控制的范围。
? navigator是什么
是 JavaScript 中的一个全局对象,提供了关于浏览器和操作系统的有用信息。它通常用于访问浏览器的状态、用户的设备信息以及其他与浏览器相关的功能。
1
navigator.userAgent # 返回一个字符串,包含了浏览器的信息,如浏览器类型、版本、操作系统等
1
navigator.platform # 返回浏览器所在操作系统的名称。常见的返回值包括 "Win32", "Linux x86_64", "MacIntel" 等。
1
navigator.onLine # 返回一个布尔值,表示浏览器是否处于在线状态(即是否连接到互联网)
1
navigator.language # 返回浏览器的首选语言设置。通常返回类似 en-US、zh-CN 这样的语言标识符。
1
navigator.geolocation # 是一个对象,提供定位服务。
1
navigator.connection # 提供网络连接的详细信息,如网络类型(Wi-Fi、4G等)和带宽。
1
navigator.vendor # 返回浏览器的供应商名,如 "Google Inc."、"Apple Computer, Inc." 等。
1
navigator.cookieEnabled / navigator.plugins / navigator.deviceMemory...
三、Service Worker 文件(sw.js)的代码示例
① 定义缓存名称和缓存资源列表
1 |
|
② 安装事件 install
安装阶段,会预缓存一些必要的资源。
1 |
|
**?**为什么要加上event.waitUntil
默认情况下,Service Worker 的事件处理函数是 同步执行 的。如果直接把异步操作(比如缓存文件)放在事件处理函数中,事件处理器会继续执行,并且很快结束,而异步操作可能还没有完成。so,为了确保事件处理函数等待异步操作完成后才结束,保证了操作的完整性。
?caches是什么
是 Service Worker API 中的一个全局对象,
caches
对象提供了几种常用的操作方法,比如:
1
caches.open(cacheName) # 打开一个缓存,如果缓存不存在,则会创建一个新的缓存。返回一个 Promise,该 Promise 成功时会返回一个 Cache 对象。
1
caches.match(request) # 查找缓存中是否已经有与给定请求(request)匹配的响应。如果找到,会返回一个 Response 对象。
1
caches.delete(cacheName) # 删除指定名称的缓存。返回一个 Promise,表示删除操作的结果。
1
caches.has(cacheName) # 检查指定的缓存是否存在。返回一个 Promise,如果存在,Promise 会返回 true,否则返回 false。
③ 激活事件 activate
激活阶段通常用于清理旧版本缓存,确保客户端使用最新的资源。
1 |
|
④ 拦截网络请求事件 fetch
通过监听 fetch
事件,Service Worker 可以拦截所有网络请求,并根据缓存情况返回相应资源,从而实现离线支持。
1 |
|
? response 只能使用一次什么意思
在处理 HTTP 请求时,服务器的响应是一次性的。例如,收到一个 HTTP 响应后,你可以读取响应体、状态码等信息,但是如果你已经读取过响应体内容(比如通过
.json()
或.text()
方法),这个响应体内容就不能再读取一次。第二次访问会抛出错误或返回null
,因为响应体已经被消耗了。这是因为大多数响应对象(比如 HTTP 响应)是 流式的,即数据是在网络传输过程中逐步到达的。读取数据时就会把它“消耗”掉,后续就无法再访问这些已经消耗的数据。为了避免重复读取,可以在获取数据时尽早存储一份副本。
⑤ 后台同步 sync
后台同步允许在网络恢复时执行延迟的任务。使用示例如下(需浏览器支持 Sync API):
1 |
|
? event.tag 是什么
用来识别事件的类型或者标识某个特定的同步任务。后台同步允许在用户的网络连接恢复时,浏览器通过 Service Worker 自动发送请求来同步未完成的操作。例如,用户在离线时提交了一个表单,Service Worker 会将此请求保存并在恢复连接后进行同步。sync 事件会带有一个 tag,可以用它来区分不同的同步任务。
⑥ 推送通知 push
1 |
|
四、调试与注意事项
调试:
现代浏览器(如 Chrome 和 Firefox)在开发者工具中提供了专门的 Service Worker 调试面板,可以查看注册情况、日志和缓存内容。
HTTPS 环境:
Service Worker 仅在 HTTPS 环境下工作(或在 localhost 开发环境中),以确保安全性。
注册:在主页面通过 navigator.serviceWorker.register()
注册 Service Worker 文件。
生命周期:包括 install
(安装、预缓存资源)、activate
(激活、清理旧缓存)以及 fetch
(拦截网络请求)等事件。Service Worker 的安装和激活可能需要一些时间,更新机制(如 skipWaiting()
和 clients.claim()
)可以帮助加速新版本的激活,但也需要谨慎使用。