作用:
可以使你的应用先访问本地缓存资源,所以在离线状态时,在没有通过网络接收到更多的数据前,仍可以提供基本的功能。
使用前的设置:
Chrome中需要开启相关配置: 访问 chrome://flags 并开启 experimental-web-platform-features; 重启浏览器 (注意:有些特性在Chrome中没有默认开放支持);另外,你需要通过 HTTPS 来访问你的页面 — 出于安全原因,Service Workers 要求要在必须在 HTTPS 下才能运行,localhost 也被浏览器认为是安全源。
简单的例子
这是把express和sw-test简单结合的一个小demo, 项目运行起来访问
http://localhost:3000/sw-test/index.html , 然后终止此服务依然能访问相应资源。Github
相关代码
- /public/sw-test/app.js
- 首先判断了浏览器是否支持
- 调用 register 方法注册 service worker, 第一个参数是运行 service worker 的
js 文件, 第二个 scope 参数是选填的,可以被用来指定你想让 service worker 控制的内容的子目录。 在这个例子,我们指定了 '/sw-test/',即 http://localhost:3000/sw-test/ 下的请求会被捕获, 被指定的资源会被缓存。 - register 方法返回一个 Promise , 进行正确错误处理。
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw-test/sw.js', { scope: '/sw-test/' }).then(function(reg) {
// registration worked
console.log('Registration succeeded. Scope is ' + reg.scope);
}).catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
}
-
/public/sw-test/sw.js
核心文件,监听安装事件, 打开缓存 v1 增加需要缓存资源 request url list, 截取被控文件下请求, 如果不存在该缓存则进行缓存处理
- 监听了 install 事件, event.waitUntil 主要用在 Install, activate 事件中, 在服务工作线程中,延长事件的寿命从而阻止浏览器在事件中的异步操作完成之前终止服务工作线程。
-
Cache 接口提供缓存的 Request,
Response 对象对的存储机制,例如作为ServiceWorker
生命周期的一部分。 Cache 接口像 workers 一样, 是暴露在 window 作用域下的。尽管它被定义在 service worker 的标准中, 但是它不必一定要配合 service worker 使用.Cache详细API - event.respondWith 方法旨在包裹代码,这些代码为来自受控页面的request生成自定义的response,查看更多。response.clone() 创建了一个响应对象的克隆,这个对象在所有方面都是相同的,但是存储在一个不同的变量中。防止多次使用篡改了对象。
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open('v1').then(function(cache) {
return cache.addAll([
'/sw-test/',
'/sw-test/index.html',
'/sw-test/style.css',
'/sw-test/app.js',
'/sw-test/image-list.js',
'/sw-test/star-wars-logo.jpg',
'/sw-test/gallery/bountyHunters.jpg',
'/sw-test/gallery/myLittleVader.jpg',
'/sw-test/gallery/snowTroopers.jpg'
]);
})
);
});
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request).then(function(response) {
// caches.match() always resolves
// but in case of success response will have value
if (response !== undefined) {
return response;
} else {
return fetch(event.request).then(function (response) {
// response may be used only once
// we need to save clone to put one copy in cache
// and serve second one
let responseClone = response.clone();
caches.open('v1').then(function (cache) {
cache.put(event.request, responseClone);
});
return response;
}).catch(function () {
return caches.match('/sw-test/gallery/myLittleVader.jpg');
});
}
}));
});
版本更新删除旧缓存
- 监听 activate 事件, 如当前版本 v2,删除与当前不匹配缓存数据。
this.addEventListener('activate', function(event) {
var cacheWhitelist = ['v2'];
event.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (cacheWhitelist.indexOf(key) === -1) {
return caches.delete(key);
}
}));
})
);
});
网友评论