前生: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 向用户发出通知
负责所有与通知本身相关的机制,如通知权限管理、向操作系统发起通知、通知类型与音效,以及提供通知被点击或关闭时的回调等;