service-worker实践

Posted lmh2072005

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了service-worker实践相关的知识,希望对你有一定的参考价值。

service-worker虽然已列入标准,但是支持的浏览器还是有限制,还有比较多的问题。

1. 生命周期

注册成功-------installing--------------> 安装成功(installed)(waiting) ---------activating----------> 激活成功 (activated)------> 销毁(redundant)
其中任何一个步骤失败都将进入销毁(redundant)
a. 注册:

调用 navigator.serviceWorker.register 方法,第一个参数是 service-worker对应的js文件, 第二个参数可选,scope是表示 service-worker 的作用域,最大的作用域就是 service-worker.js所在目录。

这2个参数都相对于origin目录,而不是项目根目录。

比如 https://mdn.github.io/sw-test/sw.js ,项目根目录是 https://mdn.github.io/sw-test/,路径应该写成 /sw-test/sw.js 而非 /sw.js.

不写scope默认就是最大的作用域,{scope: ‘/service-worker/foo/‘} 表示service-worker只在foo目录下生效,不过尝试设置了下没什么用,在chrome下一直是最大作用域。

navigator.serviceWorker.(‘/service-worker/service-worker.js‘, {scope: ‘/service-worker/foo/‘})
        .then(function (registration) {
            console.log(‘registration:‘,registration);
        })
        .catch(function (e) {
            console.error(e);
 })

b. 安装

注册成功后进入installing状态,这时会触发 install 事件, 在这个事件里面我们可以添加文件到缓存,如果不调用 skipWaiting 当前sw会在安装成功后进入waiting状态,直到所有页面都没有被旧的sw控制为止。

调用skipWaiting 将使当前sw直接进入 activating 状态。在开发调试时最好设置skipWaiting ,否则刷新页面新的sw一直处于waiting而不被使用。

self.addEventListener(‘install‘, function (event) { //  监听worker的install事件
     self.skipWaiting();//让新 SW 立即激活。这里不会跳过 installing,  只会等安装成功后跳过 waiting直接将之前存在的sw销毁,新的sw进入到activating
    event.waitUntil( // 延迟install事件直到缓存初始化完成
        caches.open(CACHE_VERSION)
            .then(function (cache) {
                console.log(‘Opened cache‘);
                return cache.addAll(CACHE_FILES); // 会从网络加载需要缓存的文件,这时当前sw的fetch还没监听
            })
    );
});

3. 激活

sw从waiting状态进入到 activating 这时会触发 activate 事件, 可以在这个事件里面处理缓存的清理功能,这里要注意 self.clients.claim ,假如页面没有sw控制,这个方法可以让当前页面马上sw控制,在控制之后的请求都会被fetch监听到,如果没有调用这个方法就必须刷新页面或关了页面重新进来页面才会被sw控制。

self.addEventListener(‘activate‘, function (event) { // 监听worker的activate事件

    event.waitUntil( // 延迟activate事件直 到
        caches.keys().then(function(keys){
            return Promise.all(keys.map(function(key, i){   // 清除旧版本缓存
                if(key !== CACHE_VERSION){
                    //console.log(keys, key)
                    return caches.delete(keys[i]);
                }
            }))
        })
    )

    //When a service worker is initially registered, pages won‘t use it until they next load. The claim() method causes those pages to be controlled immediately.
    self.clients.claim(); //让没被控制的 clients(页面、workers) 受控, 否则要刷新页面才受控,比如资源加载触发fetch(可以设置延时加载模拟)
});

激活成功后进入activated状态,这时fetch、message、put事件被触发。

self.addEventListener(‘fetch‘, function(event) {  
  // Do stuff with fetch events
});

self.addEventListener(‘message‘, function(event) {  
  // Do stuff with postMessages received from document
}); 

可以利用fetch事件监听资源请求,进行修改响应或请求,发现请求资源没在缓存列表,可以从网络加载资源,并添加到缓存列表

 

以上是关于service-worker实践的主要内容,如果未能解决你的问题,请参考以下文章

Service-Worker,“TypeError:<anonymous> 处的请求失败”

与 Angular.js 控制器通信 service-worker

service-worker 可以停止 GCM api 发送的推送通知吗?

使用 create-react-app 添加更多 service-worker 功能

Service-Worker addEventListener,如何使用事件参数?

逆向及Bof基础实践