Progressive Web App, 简称 PWA,是提高 Web App 的体验的一种新方法,能给用户原生应用的体验。Service Worker 是 PWA 中的重要一部分。Service Worker 能够监听当前域下的功能性事件,好比拦截和处理网络请求、推送通知(push)、后台同步(sync),今天咱们来了解一下 Service Workercss
Service worker (简称 SW) 是一个注册在指定源和路径下的事件驱动 Worker。它采用 JavaScript 控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。你能够彻底控制应用在特定情形(最多见的情形是网络不可用)下的表现。html
首先,咱们经过 js 代码调用浏览器的 api,注册 SW,告诉浏览器 SW 文件的位置,Service Worker 支持 promise,因此写起来很是方便git
// main.js if (navigator.serviceWorker) { window.addEventListener('DOMContentLoaded', () => { navigator.serviceWorker .register('sw.js') .then(function(swReg) { console.log('sucess ~', swReg); }) .catch(function(error) { console.error('fail !', error); }) }) }
sw 存在做用域的概念,上面注册的做用域为 '/',若是注册的 js 文件地址为 'a/sw.js',则 sw 的做用域为 '/a'github
接下来的代码编写主要集中在 sw.js (sw 加载的 js 文件) 文件中,在 Service Worker 安装过程当中,咱们进行数据的缓存。缓存文件的重要角色是浏览器的 Cache API,将数据缓存下来。web
const cacheName = 'myCache' const cacheArray = [ '/index.html', '/index.css', '/main.js' ] self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( // 打开一个 Cache 对象 caches.open(CACHE_NAME) .then(function(cache) { // 缓存数组中的内容 return cache.addAll(urlsToCache); }) ) })
由于一个 Worker是使用一个构造函数建立的一个对象运行一个命名的JavaScript文件。这个文件包含将在工做线程中运行的代码,运行在另外一个全局上下文中,不一样于当前的window。在 sw.js 中,没法使用 window、操做 DOM 等,使用 self 关键字,来实引用 DedicatedWorkerGlobalScope。若是全部文件都成功缓存,则将安装 Service Worker。 若有任何文件没法下载,则安装步骤将失败。也意味着 Service Worker 启动失败api
event.waitUntil
确保浏览器关闭也仍然可以执行数组
Service Worker 可以实现离线功能,主要是拥有代理请求的功能,咱们可以在请求的时候有本身的操做空间,请求优先,请求失败从 Cache 读取缓存;请求成功,更新缓存。promise
self.addEventListener('fetch', (event) => { if (event.request.mode === 'navigate') { return event.respondWith( fetch(event.request).catch(() => caches.match(OFFLINE_URL)) ) } })
event.respondWith
在 sw.js 的内部经过事件监听的方式执行对应的回调函数,接收外部的推送信息,只须要添加 push 事件监听便可浏览器
self.addEventListener('push', function(event) { const options = { body: 'Yay it works.', icon: 'images/icon.png', badge: 'images/badge.png' } self.registration.showNotification(title, options); })
消息推送,配合 Web Server For Chrome 更方便~
在浏览器无网络请状况下,服务端推送消息,浏览器没法接收到,可是当网络连通时,浏览器就能够接收到服务端推送的信息。浏览器的请求也能够实现一样的功能,经过特殊的方式发送请求,网络连通时,请求才会发出去。缓存
// 请求 navigator.serviceWorker.ready.then((registration) => { // 区分不一样的事件 const tag = 'tag'; registration.sync.register(tag).then(() => { // do something... }) }) // 事件监听 // sw.js self.addEventListener('sync', function (e) { console.log(e.tag === 'tag') // true e.waitUntil(...) })
Firebase 云信息传递 (FCM) 是一种跨平台消息传递解决方案,可供您免费、可靠地传递消息。能够发送通知消息以再次吸引用户并留住他们。在即时通信等使用情形中,一条消息可将最多 4KB 的有效负载传送至客户端应用。
浏览器的 Service Worker 的消息推送主要依赖 FCM,服务端消息推送传递到 FCM,而后再由 FCM 推送到客户端。
参考连接: