简介

操作

检测ServiceWorker

首先我们要做的是检测当前浏览器是否支持ServiceWorker,目前Firefox和Chrome浏览器支持。

  1. if ('serviceWorker' in navigator) {
  2. navigator.serviceWorker.register(sw.js) // 注册sw.js 文件中变成的服务对象,返回注册成功的对象
  3. .then(function(swReg){
  4. swRegistration = swReg;
  5. }).catch(function(error) {
  6. console.error('Service Worker Error', error);
  7. });
  8. }

注册ServiceWorker

你需要引入 Service Worker,这是一个 js 文件,一般命名为 sw.js ,通常放在项目的根目录。
通常在浏览器端进行本地存储,可以运用 CookiesSessionLocalStoargeCacheStorage 实现。
要实现页面缓存,这里就要运用到 CacheStorage
它提供了一个 ServiceWorker 类型的工作者或 window 范围可以访问的所有命名缓存的主目录, 并维护字符串的映射名称到相应的 Cache 对象。
PWA 通过 ServiceWorker 访问 cache ,所以需要注册 ServiceWorker 工作者。

  1. // sw.js
  2. 'use strict'
  3. let cacheName = 'pwa-demo-assets'; // 缓存名字
  4. let imgCacheName = 'pwa-img';
  5. let filesToCache;
  6. filesToCache = [ // 所需缓存的文件
  7. '/',
  8. '/index.html',
  9. '/scripts/app.js',
  10. '/assets/imgs/48.png',
  11. '/assets/imgs/96.png',
  12. '/assets/imgs/192.png',
  13. '/dist/js/app.js',
  14. '/manifest.json'
  15. ];
  16. self.addEventListener('install', function(e) {
  17. e.waitUntil(
  18. // 安装服务者时,对需要缓存的文件进行缓存
  19. caches.open(cacheName).then(function(cache) {
  20. return cache.addAll(filesToCache);
  21. })
  22. );
  23. });
  24. self.addEventListener('fetch', (e) => {
  25. // 判断地址是不是需要实时去请求,是就继续发送请求
  26. if (e.request.url.indexOf('/api/400/200') > -1) {
  27. e.respondWith(
  28. caches.open(imgCacheName).then(function(cache){
  29. return fetch(e.request).then(function (response){
  30. cache.put(e.request.url, response.clone()); // 每请求一次缓存更新一次新加载的图片
  31. return response;
  32. });
  33. })
  34. );
  35. } else {
  36. e.respondWith(
  37. // 匹配到缓存资源,就从缓存中返回数据
  38. caches.match(e.request).then(function (response) {
  39. return response || fetch(e.request);
  40. })
  41. );
  42. }
  43. });

注册ServiceWorker部分逻辑如下:

  1. if ('serviceWorker' in navigator) {
  2. navigator.serviceWorker.register(sw.js)
  3. .then(function(swReg) {
  4. doSomething()
  5. })
  6. .catch(function(error) {
  7. console.error('Service Worker Error', error);
  8. });
  9. } else {
  10. console.warn('serviceWorker is not supported');
  11. }

注册PushManager

基本原理是,客户端要和推送服务进行绑定。
在推送服务端会生成一个绑定后的推送服务 API 接口,服务端可以通过调用此接口,发送消息。
前提是,浏览器需要支持推送功能,在注册 sw 时, 加上推送功能的判断。

  1. if ('serviceWorker' in navigator && 'PushManager' in window) {
  2. navigator.serviceWorker.register(sw.js)
  3. .then(function(swReg) {
  4. swRegistration = swReg;
  5. }).catch(function(error) {
  6. console.error('Service Worker Error', error);
  7. });
  8. } else {
  9. console.warn('Push messaging is not supported');
  10. }

绑定推送服务

PushManager 注册好之后, 那么要做的就是浏览器和服务器的绑定了。
Web Push - 图1
上图是用户订阅某个应用程序的推送服务,流程梳理如下:

  1. 客户端 附带着应用程序服务器公钥向推送服务器(Webpush,Google实现)发出订阅请求
  2. 推送服务端 将生成的端点(推送服务地址)与应用程序的公钥关联,再返回端点给客户端
  3. 客户端浏览器 将端点添加到 PushSubscription

    服务器端发起推送

Web Push - 图2
服务器发送推送的时候,请求相关接口,验证成功后推送服务会发消息给客户端。