认识
一、认识
Service Worker
是一种运行在浏览器后台的脚本,位于应用程序和网络之间的中间层,允许开发者拦截和处理网络请求,从而实现离线支持、资源缓存、推送通知等功能。它是 PWA
(Progressive Web Apps
)的核心技术之一。
Service worker
本质上充当 Web
应用程序、浏览器与网络(可用时)之间的代理服务器。这个 API
旨在创建有效的离线体验,它会拦截网络请求并根据网络是否可用来采取适当的动作、更新来自服务器的资源。它还提供入口以推送通知和访问后台同步 API
。Service Worker
在浏览器后台运行,与主线程隔离,因此不会阻塞页面渲染。可以通过事件监听(如 fetch
)来拦截并处理网页的网络请求。通过 Cache API
,可以缓存静态资源,实现离线访问和快速加载。Service Worker
有明确的安装(install
)、激活(activate
)、运行(fetch
)等生命周期。必须在 HTTPS
环境下运行(或者在 localhost
开发环境中允许非 HTTPS
)。Service Worker
运行在独立的线程中,无法直接操作 DOM
。
Service Worker
工作流:
1. 注册 Service Worker
: Service Worker
使用 ServiceWorkerContainer.register()
方法首次注册 service worker
。如果注册成功,用户首次访问 service worker
控制的网站或页面时,service worker
会立刻被下载。service worker
将在 ServiceWorkerGlobalScope
中执行;这本质上是一种特殊的上下文,在主脚本执行线程之外运行,没有访问 DOM
的权限。Service Worker
现在已为处理事件做好准备。
2. 安装(install
): 在浏览器下载并解析完 Service Worker
文件后触发。通常用于缓存静态资源。当下载的文件发现是最新的时,就会试图安装——要么与现有的 service worker
不同(字节对比),要么是在页面或网站遇到的第一个 service worker
。如果这是首次启用 service worker
,页面会首先尝试安装,安装成功后它会被激活。install
事件始终是发送给 service worker
的第一个事件(这可用于启动填充 IndexedDB
和缓存站点资源的过程)。在此步骤期间,应用程序正在为离线可用做准备。
3. 激活(activate
): 新的 Service Worker
替换旧的后触发。常用于清理旧的缓存或初始化资源。如果现有 service worker
已启用,新版本会在后台安装,但仍不会被激活——这个时序称为 worker in waiting
。直到所有已加载的页面不再使用旧的 service worker
才会激活新的 service worker
。只要页面不再依赖旧的 service worker
,新的 service worker
会被激活(成为 active worker
)。一旦 service worker
的旧版本控制的页面都已关闭,就可以安全地停用旧版本,并且新安装的 service worker
将收到 activate
事件。activate
的主要用途是去清理 service worker
之前版本使用的资源。新的 service worker
可以调用 skipWaiting()
要求立即激活,而无需要求打开的页面关闭。然后,新的 service worker
将立即收到 activate
事件,并将接管任何打开的页面。激活后,service worker
将立即控制页面,但是只会控制那些在 register()
成功后打开的页面。换句话说,文档必须重新加载才能真正的受到控制,因为文档在有或者没有 service worker
的情况下开始存在,并在其生命周期内维护它。为了覆盖次默认行为并在页面打开的情况下,service worker
可以调用 clients.claim()
方法。每当获取新版本的 service worker
时,都会再次发生此循环,并在新版本的激活期间清理上一个版本的残留。
4. 运行(fetch
、push
): 激活后的 Service Worker
监听 fetch
等事件,控制网络请求。
5. 更新(update
): 浏览器检测到 Service Worker
文件发生变化时,下载新文件并安装。一个前往作用域内页面的导航或者在 service worker
上的一个事件被触发并且过去 24
小时没有被下载时会触发更新
Service Worker
可用事件:
-
install
: 通过ServiceWorkerContainer.register()
注册完成, 用户首次访问service worker
控制的网站或页面时,service worker
会立刻被下载。 在浏览器下载并解析完Service Worker
文件后触发install
事件。install
事件通常会这样用,将离线运行app
产生的资源放置在浏览器离线缓存的空间。 -
activate
: 新的Service Worker
替换旧的后触发。 -
message
-
fetch
-
sync
-
push
二、语法
2.1 创建 Service Worker
service-worker.js
文件
self.addEventListener("install", (event) => {
console.log('Service Worker 安装中...');
});
self.addEventListener('activate', event => {
console.log('Service Worker 激活');
});
self.addEventListener('fetch', event => {
console.log('拦截请求:', event.request.url);
});
2.2 主线程注册 Service Worker
使用 ServiceWorkerContainer.register()
方法首次注册 service worker
。
const registerServiceWorker = async () => {
if ("serviceWorker" in navigator) {
try {
const registration = await navigator.serviceWorker.register("/sw.js", {
scope: "/",
});
if (registration.installing) {
console.log("正在安装 Service worker");
} else if (registration.waiting) {
console.log("已安装 Service worker installed");
} else if (registration.active) {
console.log("激活 Service worker");
}
} catch (error) {
console.error(`注册失败:${error}`);
}
}
};
registerServiceWorker();