前生:AppCache
AppCache 最初是作为 HTML5 规范的一部分引入,用以解决离线 web 应用程序的问题。
AppCache 最终被发现是不实用的和充满陷阱的。因此它已被废弃,被 Service Workers 有效的取代。
今世:Service worker
Service worker 提供了一个更具前瞻性的离线应用解决方案,通过更加程序化的语言书写规则替代 AppCache 的声明式书写方式。
Service Worker 在浏览器后台进程中持续的执行其代码。它是事件驱动的,这意味着在 Service Worker 的作用域范围内触发的事件会驱动其行为。
在前端代码中某一处执行以下代码即可
if (navigator.serviceWorker) { navigator.serviceWorker.register('./service-worker.js', {scope: './'}) .then(function (registration) { console.log(registration); }) .catch(function (e) { console.error(e); }) } else { console.log('Service Worker is not supported in this browser.') }
这将告诉浏览器在哪里找到你的 Service Worker 的实现,浏览器将查找对应的(/service-worker.js)文件,并将它保存在你正在访问的域名下,这个文件将包含所有你自己定义的 Service Worker 事件处理程序
在执行注册的操作的同时也确认了你的ServiceWorker的作用范围是在URL的根路径下。这意味着在你的根路径下的任何请求,都将通过触发事件的方式告诉 Service Worker。一个文件路径为/js/service-worker.js的文件就仅仅可以捕获http://{host}/js该链接下的请求。
另外,你也可以通过将第二个参数传入给register方法来明确地设置 Service Worker 的作用域范围:
navigator.serviceWorker.register('/sw.js', { scope: '/js' })
实际上离线缓存功能,就是我们根据WebApp的需要,事先将缓存策略写入到service-worker.js中。接下来通过分析service-worker.js的代码来介绍该功能的实现。
var CACHE_VERSION = 'app-v1'; var CACHE_FILES = [ ... ]; self.addEventListener('install', function (event) { console.log('install', event) event.waitUntil( caches.open(CACHE_VERSION) .then(function (cache) { console.log('Opened cache'); return cache.addAll(CACHE_FILES); }) ); });
self.addEventListener('activate', function (event) { console.log('activate', event) event.waitUntil( caches.keys().then(function (keys) { return Promise.all(keys.map(function (key, i) { if (key !== CACHE_VERSION) { return caches.delete(keys[i]); } })) }) ) });
self.addEventListener('fetch', function (event) { console.log('fetch', event) event.respondWith( caches.match(event.request).then(function (res) { if (res) return res; requestBackend(event); }) ) }); function requestBackend (event) { console.log('requestBackend', event) var url = event.request.clone(); return fetch(url).then(function (res) { //if not a valid response send the error if (!res || res.status !== 200 || res.type !== 'basic') return res; var response = res.clone(); caches.open(CACHE_VERSION).then(function (cache) { cache.put(event.request, response); }); return res; }) }
Push API 让推送服务具备了向 web 应用推送消息的能力;
它定义了 web 应用如何向推送服务发起订阅、如何响应推送消息、web 应用和服务器与推送服务之间的鉴权与加密机制;
由于 Push API 并不依赖 web 应用与浏览器 UI 存活,所以即使是在 web 应用与浏览器未被用户打开的时候,也可以通过后台进程接受推送消息并调用 Notification API 向用户发出通知
负责所有与通知本身相关的机制,如通知权限管理、向操作系统发起通知、通知类型与音效,以及提供通知被点击或关闭时的回调等;