Service Worker初体验
分类:计算机知识

Service Worker初体验

2016/01/06 · JavaScript · Service Worker

原稿出处: AlloyTeam   

在二〇一六年,W3C公布了service worker的草案,service worker提供了无数新的力量,使得web app具备与native app雷同的离线体验、音信推送体验。
service worker是少年老成段脚本,与web worker雷同,也是在后台运转。作为一个单独的线程,运转条件与经常脚本分裂,所以不可能直接参加web人机联作行为。native app能够完结离线使用、音信推送、后台自动更新,service worker的产出是多亏为了使得web app也能够有所相像的力量。

 

service worker可以:

  1. 后台音讯传递
  2. 网络代理,转发呼吁,假造响应
  3. 离线缓存
  4. 音讯推送
  5.  … …

本文以能源缓存为例,说美素佳儿(Friso卡塔尔下service worker是怎么行事的。

生命周期

先来看一下三个service worker的运维周期

图片 1
上航海用体育场所是service worker生命周期,出处

图中能够看看,二个service worker要经历以下进程:

  1.  安装

2.  激活,激活成功未来,展开chrome://inspect/#service-workers可以查阅到眼下运作的service worker

图片 2

  1. 监听fetch和message事件,上边二种事件会开展简易描述

  2. 销毁,是不是销毁由浏览器决定,假设贰个service worker长期不采用照旧机器内部存款和储蓄器有数,则大概会销毁那几个worker

fetch事件

在页面发起http需要时,service worker可以透过fetch事件拦截必要,並且付诸自个儿的响应。
w3c提供了贰个新的fetch api,用于替代XMLHttpRequest,与XMLHttpRequest最大不相同有两点:

1. fetch()方法再次来到的是Promise对象,通过then方法开展连续调用,裁减嵌套。ES6的Promise在改为行业内部之后,会进一层便利开辟人士。

2. 提供了Request、Response对象,若是做过后端开垦,对Request、Response应该比较熟识。前端要提倡呼吁可以经过url发起,也得以利用Request对象发起,并且Request能够复用。不过Response用在哪个地方吗?在service worker现身早先,前端确实不会融洽给和睦发新闻,不过有了service worker,就足以在阻碍必要之后依照供给发回本身的响应,对页面来讲,那一个常常的伸手结果并不曾分别,这是Response的生龙活虎处采用。

上面是在中,小编运用fetch api通过fliker的理解api获取图片的例证,注释中详尽解释了每一步的效果与利益:

JavaScript

/* 由于是get须要,直接把参数作为query string传递了 */ var URL = ''; function fetch德姆o() { // fetch(url, option)辅助三个参数,option中得以设置header、body、method音信fetch(UPAJEROL).then(function(response) { // 通过promise 对象得到相应内容,何况将响应内容依照json格式转成对象,json()方法调用之后回到的照样是promise对象 // 也能够把内容转产生arraybuffer、blob对象 return response.json(); }).then(function(json) { // 渲染页面 insertPhotos(json); }); } fetchDemo();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 由于是get请求,直接把参数作为query string传递了 */
var URL = 'https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=your_api_key&format=json&nojsoncallback=1&tags=penguins';
 
function fetchDemo() {
  // fetch(url, option)支持两个参数,option中可以设置header、body、method信息
  fetch(URL).then(function(response) {
    // 通过promise 对象获得相应内容,并且将响应内容按照json格式转成对象,json()方法调用之后返回的依然是promise对象
    // 也可以把内容转化成arraybuffer、blob对象
    return response.json();
  }).then(function(json) {
    // 渲染页面
    insertPhotos(json);
  });
}
 
fetchDemo();

fetch api与XMLHttpRequest比较,越发简洁,並且提供的作用更周密,能源获取形式比ajax更加高贵。宽容性方面:chrome 42开端补助,对于旧浏览器,能够透过合法维护的polyfill协助。

message事件

页面和serviceWorker之间能够透过posetMessage()方法发送消息,发送的音讯能够通过message事件接纳到。

这是二个双向的经过,页面可以发新闻给service worker,service worker也得以发送音讯给页面,由于这几个特点,能够将service worker作为中间纽带,使得多少个域名如故子域名下的两个页面能够自由通讯。

此处是三个小的页面之间通讯demo

行使service workder缓存文件

下边介绍几个使用service worker缓存离线文件的例子
预备index.js,用于注册service-worker

JavaScript

if (navigator.serviceWorker) { navigator.serviceWorker.register('service-worker.js').then(function(registration) { console.log('service worker 注册成功'); }).catch(function (err) { console.log('servcie worker 注册失利') }); }

1
2
3
4
5
6
7
if (navigator.serviceWorker) {
    navigator.serviceWorker.register('service-worker.js').then(function(registration) {
        console.log('service worker 注册成功');
    }).catch(function (err) {
        console.log('servcie worker 注册失败')
    });
}

在上述代码中,注册了service-worker.js作为当下路线下的service worker。由于service worker的权力超高,全数的代码都亟待是安全可相信的,所以独有https站点才得以行使service worker,当然localhost是一个特例。
登记甘休,今后起来写service-worker.js代码。
基于前边的生命周期图,在三个新的service worker被登记之后,首先会触发install事件,在service-workder.js中,能够透过监听install事件开展部分开始化职业,可能怎样也不做。
因为大家是要缓存离线文件,所以能够在install事件中初露缓存,可是只是将文件加到caches缓存中,真正想让浏览器采纳缓存文件需求在fetch事件中截留

JavaScript

var cacheFiles = [ 'about.js', 'blog.js' ]; self.addEventListener('install', function (evt) { evt.waitUntil( caches.open('my-test-cahce-v1').then(function (cache) { return cache.addAll(cacheFiles); }) ); });

1
2
3
4
5
6
7
8
9
10
11
var cacheFiles = [
    'about.js',
    'blog.js'
];
self.addEventListener('install', function (evt) {
    evt.waitUntil(
        caches.open('my-test-cahce-v1').then(function (cache) {
            return cache.addAll(cacheFiles);
        })
    );
});

先是定义了需求缓存的文件数组cacheFile,然后在install事件中,缓存这几个文件。
evt是四个Install伊夫nt对象,世袭自Extendable伊芙nt,个中的waitUntil()方法选拔三个promise对象,直到这几个promise对象成功resolve之后,才会继续运维service-worker.js。
caches是多少个CacheStorage对象,使用open()方法打开四个缓存,缓存通过名称进行区分。
赢得cache实例之后,调用addAll()方法缓存文件。

与此相类似就将文件加多到caches缓存中了,想让浏览器采取缓存,还供给拦截fetch事件

JavaScript

// 缓存图片 self.add伊芙ntListener('fetch', function (evt) { evt.respondWith( caches.match(evt.request).then(function(response) { if (response) { return response; } var request = evt.request.clone(); return fetch(request).then(function (response) { if (!response && response.status !== 200 && !response.headers.get('Content-type').match(/image/)) { return response; } var responseClone = response.clone(); caches.open('my-test-cache-v1').then(function (cache) { cache.put(evt.request, responseClone); }); return response; }); }) ) });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 缓存图片
self.addEventListener('fetch', function (evt) {
    evt.respondWith(
        caches.match(evt.request).then(function(response) {
            if (response) {
                return response;
            }
            var request = evt.request.clone();
            return fetch(request).then(function (response) {
                if (!response && response.status !== 200 && !response.headers.get('Content-type').match(/image/)) {
                    return response;
                }
                var responseClone = response.clone();
                caches.open('my-test-cache-v1').then(function (cache) {
                    cache.put(evt.request, responseClone);
                });
                return response;
            });
        })
    )
});

经过监听fetch事件,service worker能够回去本人的响应。

率先检缓存中是还是不是业已缓存了那一个央求,即便有,就直接再次回到响应,就收缩了一次网络央浼。不然由service workder发起央浼,那个时候的service workder起到了叁此中级代理的效果。

service worker需要的进程通过fetch api落成,得到response对象今后进行过滤,查看是或不是是图片文件,如若不是,就一贯重回央求,不会缓存。

倘使是图片,要先复制意气风发份response,原因是request或许response对象归于stream,只可以使用贰回,之后生机勃勃份存入缓存,另意气风发份发送给页面。
那就是service worker的无敌之处:拦截诉求,捏造响应。fetch api在这里边也起到了比相当大的效应。

 

service worker的换代很简短,只要service-worker.js的文件内容有立异,就能够动用新的脚本。然而有几许要专一:旧缓存文件的解除、新文件的缓存要在activate事件中实行,因为也许旧的页面还在接收以前的缓存文件,扑灭之后会失去效率。

 

在初次使用service worker的经过中,也遇到了风度翩翩部分标题,下边是里面八个

主题材料1. 周转时刻

service worker并非直接在后台运维的。在页面关闭后,浏览器能够继承保持service worker运营,也得以关闭service worker,那决定于与浏览器本人的行事。所以不用定义一些全局变量,举个例子下边包车型大巴代码(来自):

JavaScript

var hitCounter = 0; this.addEventListener('fetch', function(event) { hitCounter++; event.respondWith( new Response('Hit number ' + hitCounter) ); });

1
2
3
4
5
6
7
8
var hitCounter = 0;
 
this.addEventListener('fetch', function(event) {
  hitCounter++;
  event.respondWith(
    new Response('Hit number ' + hitCounter)
  );
});

归来的结果也许是不曾规律的:1,2,1,2,1,1,2….,原因是hitCounter并不曾平素留存,固然浏览器关闭了它,下一次起步的时候hitCounter就赋值为0了
如此那般的业务招致调节和测试代码困难,当您更新二个service worker以往,独有在开垦新页面未来才大概应用新的service worker,在调节和测量检验进程中通常等上风流洒脱两秒钟才会利用新的,比较抓狂。

标题2. 权力太大

当service worker监听fetch事件之后,对应的恳求都会透过service worker。通过chrome的network工具,能够看看此类恳求会标明:from service worker。要是service worker中冒出了难点,会促成全体乞请失利,富含平时的html文件。所以service worker的代码品质、容错性必供给很好技艺保险web app正常运转。

 

参照随笔:

1. 

2. 

3. 

4. 

5. 

1 赞 3 收藏 评论

图片 3

本文由六和开奖现场发布于计算机知识,转载请注明出处:Service Worker初体验

上一篇:后者当羊眼半夏件操作与上传 下一篇:离线访谈静态blog网址
猜你喜欢
热门排行
精彩图文