简介
操作
检测ServiceWorker
首先我们要做的是检测当前浏览器是否支持ServiceWorker,目前Firefox和Chrome浏览器支持。
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register(sw.js) // 注册sw.js 文件中变成的服务对象,返回注册成功的对象
.then(function(swReg){
swRegistration = swReg;
}).catch(function(error) {
console.error('Service Worker Error', error);
});
}
注册ServiceWorker
你需要引入 Service Worker,这是一个 js 文件,一般命名为 sw.js
,通常放在项目的根目录。
通常在浏览器端进行本地存储,可以运用 Cookies
、Session
、LocalStoarge
和 CacheStorage
实现。
要实现页面缓存,这里就要运用到 CacheStorage
。
它提供了一个 ServiceWorker
类型的工作者或 window 范围可以访问的所有命名缓存的主目录, 并维护字符串的映射名称到相应的 Cache 对象。
PWA 通过 ServiceWorker 访问 cache ,所以需要注册 ServiceWorker 工作者。
// sw.js
'use strict'
let cacheName = 'pwa-demo-assets'; // 缓存名字
let imgCacheName = 'pwa-img';
let filesToCache;
filesToCache = [ // 所需缓存的文件
'/',
'/index.html',
'/scripts/app.js',
'/assets/imgs/48.png',
'/assets/imgs/96.png',
'/assets/imgs/192.png',
'/dist/js/app.js',
'/manifest.json'
];
self.addEventListener('install', function(e) {
e.waitUntil(
// 安装服务者时,对需要缓存的文件进行缓存
caches.open(cacheName).then(function(cache) {
return cache.addAll(filesToCache);
})
);
});
self.addEventListener('fetch', (e) => {
// 判断地址是不是需要实时去请求,是就继续发送请求
if (e.request.url.indexOf('/api/400/200') > -1) {
e.respondWith(
caches.open(imgCacheName).then(function(cache){
return fetch(e.request).then(function (response){
cache.put(e.request.url, response.clone()); // 每请求一次缓存更新一次新加载的图片
return response;
});
})
);
} else {
e.respondWith(
// 匹配到缓存资源,就从缓存中返回数据
caches.match(e.request).then(function (response) {
return response || fetch(e.request);
})
);
}
});
注册ServiceWorker部分逻辑如下:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register(sw.js)
.then(function(swReg) {
doSomething()
})
.catch(function(error) {
console.error('Service Worker Error', error);
});
} else {
console.warn('serviceWorker is not supported');
}
注册PushManager
基本原理是,客户端要和推送服务进行绑定。
在推送服务端会生成一个绑定后的推送服务 API 接口,服务端可以通过调用此接口,发送消息。
前提是,浏览器需要支持推送功能,在注册 sw 时, 加上推送功能的判断。
if ('serviceWorker' in navigator && 'PushManager' in window) {
navigator.serviceWorker.register(sw.js)
.then(function(swReg) {
swRegistration = swReg;
}).catch(function(error) {
console.error('Service Worker Error', error);
});
} else {
console.warn('Push messaging is not supported');
}
绑定推送服务
PushManager 注册好之后, 那么要做的就是浏览器和服务器的绑定了。
上图是用户订阅某个应用程序的推送服务,流程梳理如下:
- 客户端 附带着应用程序服务器公钥向推送服务器(Webpush,Google实现)发出订阅请求
- 推送服务端 将生成的端点(推送服务地址)与应用程序的公钥关联,再返回端点给客户端
- 客户端浏览器 将端点添加到
PushSubscription
服务器端发起推送
服务器发送推送的时候,请求相关接口,验证成功后推送服务会发消息给客户端。