Open FrankKai opened 5 years ago
用户断网导致的离线问题。
chrome://flags
experimental-web-platform-features
service worker基于Promise,这样可以做到不阻塞main thread。
XMLHttpRequest API是不推荐的API,service worker推荐使用caching和onfetch,所以最好将重心放在对Promise的理解上。
在线demo:https://mdn.github.io/sw-test/ github repo:https://github.com/mdn/sw-test
Worker interface繁衍出来真正的操作系统级别的线程,所以可能会有线程并发导致的问题。 service worker 这样的web worker,可以很好地控制和其他线程的通信节点,因此不用担心线程并发导致的问题。 service worker这样的web worker,传入传出数据到线程,需要通过序列化的对象。
不完全可以。 因为service worker工作在DedicatedWorkerGlobalScope(实现了WorkerGlobalScope),window工作在WorkerGlobalScope(实现了Window和WorkerGlobalScope)。 但是可以使用很多在window环境下可以使用的技术,例如websocket,数据存储等等。可以查阅Functions and classes available to workers
不可以。 因为service worker这样的web worker,没有非线程安全组件和DOM的权限。
chrome://inspect/#service-workers
-当前的service-worker信息
chrome://serviceworker-internals
-可以start、stop、debug service worker process
✅启用Service Workers over HTTP
firefox developer tool
Application->Service Workers->Service workers from other origins
可以查看到其他origin的service worker
1.注册serviceWorkerContainer.register()
抓取并注册service worker URL。
2.作用域service worker工作在ServiceWrokerGlobalScope
,无DOM权限。
3.监听此时可以处理events了。
4.安装中获取到权限后,worker可以开始安装。Install事件会首先发送到service worker(此时可以填充数据到IndexedDB,缓存网站静态资源)。这与安装一个原生app一样,此时app可以离线使用了。
5.安装成功oninstall
处理器完成后,service worker安装成功。
6.激活当前service worker安装成功后,service worker收到一个activate event。onactivate
事件主要用来清除上一个版本的Service worker脚本的资源。
7.service worker控制页面service worker此时开始控制页面,但仅仅能控制register()
后开启的页面。document在有没有service worker的情况下都可以工作,所以若service worker想控制document,需要重新加载。
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);
});
}
navigator.serviceWorker.register()
本质上是navigator的serviceWorker getter生成的函数,而这个getter其实是基于ServiceWorkerContainer这个类生成的。'/sw-test/sw.js'
是相对window.origin的路径,window.origin在有权威域名的情况下,返回权威域名,about:blank
及data:text/html,<b>love you</b>
情况下返回null。scope:'/sw-test/'
代表我们app的所有内容都在这个目录下,service worker可以进行控制目录下内容,scope是可选的,默认值就是'/sw-test/'
。.then()
是为了确保service worker注册成功后再执行代码。其他注意事项:
self.addEventListener('install', (event)=>{
event.waitUntil(
caches.open('v1').then((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',
'./sw-test/gallery/bountryHunters.jpg',
'./sw-test/gallery/myLittleVader.jpg',
'./sw-test/gallery/snowTroppers.jpg'
])
})
)
})
注意:
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
);
});
new Response('Hello from your friendly neighbourhood service worker!');
new Response('<p>Hello from your friendly neighbourhood service worker!</p>', {
headers: { 'Content-Type': 'text/html' }
});
fetch(event.request);
caches.match('./fallback.html');
event.request.url
event.request.method
event.request.headers
event.request.body
可以像下面这样处理异常:
self.addEventListener('fetch', (event)=>{
event.respondWith(
caches.match(event.request).then((response)=>{
return response || fetch(event.request).then((response) => {
return caches.open('v1').then((cache) => {
cache.put(event.request, response.clone());
return response;
});
});
}).catch(()=> {
return caches.match('./sw-test/gallery/myLittleVader.jpg');
})
)
})
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('v2').then((cache) => {
return cache.addAll([
'./sw-test/',
'./sw-test/index.html',
'./sw-test/style.css',
'./sw-test/app.js',
'./sw-test/image-list.js',
…
// include other new resources for the new version...
]);
})
);
});
可以通过caches.keys()获得所有的cache的key,然后删除掉旧的,只保留新的
self.addEventListener('activate', (event) => {
var cacheKeeplist = ['v2'];
event.waitUntil(
caches.keys().then((keyList) => {
return Promise.all(keyList.map((key) => {
if (cacheKeeplist.indexOf(key) === -1) {
return caches.delete(key);
}
}));
})
);
});
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers