http://www.web008.net

Service Worker入门

Service Worker入门

2015/03/26 · JavaScript · Service Worker

原来的文章出处: Matt Gaunt   译文出处:[w3ctech

  • 十年踪迹]()   

原生App具备Web应用普通所不持有的富离线体验,定期的沉默更新,音讯公告推送等职能。而新的Serviceworkers规范让在Web App上享有那几个效应成为恐怕。

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.  … …

正文以财富缓存为例,说圣元(Synutra)(Karicare)下service worker是如何工作的。

Service Worker 是什么?

贰个 service worker 是意气风发段运转在浏览器后台进程里的脚本,它独立于当下页面,提供了那么些不供授予web页面交互的效劳在网页背后悄悄推行的力量。在以往,基于它能够实现音讯推送,静默更新以致地理围栏等劳务,但是当前它首先要负有的效果与利益是阻挠和拍卖网络央求,包涵可编程的响应缓存处理。

为何说那么些API是四个老大棒的API呢?因为它使得开垦者能够援救非常好的离线体验,它付与开辟者完全调整离线数据的技艺。

在service worker提议从前,别的叁个提供开采者离线体验的API叫做App Cache。不过App Cache有个别局限性,比方它能够非常轻便地减轻单页应用的主题素材,可是在多页应用上会很麻烦,而Serviceworkers的产出正是为了缓和App Cache的痛点。

上面详细说一下service worker有如何需求静心的地点:

  • 它是JavaScript Worker,所以它没办法直接操作DOM。可是service worker能够因此postMessage与页面之间通信,把音信公告给页面,假若要求的话,让页面自个儿去操作DOM。
  • Serviceworker是三个可编制程序的网络代理,允许开拓者调整页面上管理的网络央求。
  • 在不被应用的时候,它会协和终止,而当它再也被用到的时候,会被重复激活,所以你不可能依附于service worker的onfecth和onmessage的管理函数中的全局状态。假如您想要保存一些悠久化的音讯,你能够在service worker里使用IndexedDB API。
  • Serviceworker大量使用promise,所以借使您不驾驭如何是promise,那你须求先读书这篇文章。

生命周期

先来看一下贰个service worker的周转周期

美高梅手机版 1
上海教室是service worker生命周期,出处

图中能够见到,三个service worker要经历以下进度:

  1.  安装

2.  激活,激活成功之后,张开chrome://inspect/#service-workers能够查阅到当前运营的service worker

美高梅手机版 2

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

  2. 销毁,是不是销毁由浏览器决定,倘使二个service worker长时间不使用也许机器内部存款和储蓄器有数,则大概会销毁那么些worker

Service Worker的生命周期

Service worker具备三个截然独立于Web页面包车型地铁生命周期。

要让三个service worker在你的网址上生效,你必要先在您的网页中注册它。注册三个service worker之后,浏览器会在后台默默运转二个service worker的装置进程。

在安装过程中,浏览器会加载并缓存一些静态能源。假使具有的文本被缓存成功,service worker就设置成功了。假如有任何公文加载或缓存战败,那么安装进程就能倒闭,service worker就不能够被激活(也即未能安装成功)。假诺发生那样的主题素材,别顾忌,它会在下一次再尝试安装。

当安装完结后,service worker的下一步是激活,在此风姿罗曼蒂克等第,你还是能够升官二个service worker的版本,具体内容大家会在末端讲到。

在激活之后,service worker将接管全数在投机管辖域范围内的页面,可是假若三个页面是刚刚注册了service worker,那么它那一次不会被接管,到下三回加载页面包车型大巴时候,service worker才会生效。

当service worker接管了页面之后,它可能有三种状态:要么被终止以节约内部存款和储蓄器,要么会管理fetch和message事件,那七个事件分别发生于叁个互联网央求出现依然页面上发送了三个新闻。

下图是一个简化了的service worker初次安装的生命周期:

美高梅手机版 3

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 fetchDemo() { // fetch(url, option)援助四个参数,option中得以设置header、body、method信息fetch(USportageL).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扶助。

在我们初阶写码从前

从这个体系地址拿到chaches polyfill。

这个polyfill支持CacheStorate.match,Cache.add和Cache.addAll,而现在Chrome M40实现的Cache API还不曾支持那么些措施。

将dist/serviceworker-cache-polyfill.js放到你的网站中,在service worker中通过importScripts加载进来。被service worker加载的本子文件会被活动缓存。

JavaScript

importScripts('serviceworker-cache-polyfill.js');

1
importScripts('serviceworker-cache-polyfill.js');

需要HTTPS

在开荒阶段,你能够由此localhost使用service worker,可是大器晚成旦上线,就要求你的server帮助HTTPS。

你能够透过service worker胁制连接,伪造和过滤响应,极其逆天。尽管你能够约束自个儿不干坏事,也许有人想干坏事。所感觉了防卫旁人使坏,你只好在HTTPS的网页上登记service workers,那样大家才方可防守加载service worker的时候不被混蛋篡改。(因为service worker权限非常的大,所以要防守它本人被歹徒篡改利用——译者注)

Github Pages恰巧是HTTPS的,所以它是二个不错的自发实验田。

倘使你想要令你的server支持HTTPS,你要求为您的server拿到二个TLS证书。分裂的server安装方法不相同,阅读辅助文书档案并经过Mozilla’s SSL config generator问询最棒实行。

message事件

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

那是二个双向的进程,页面能够发新闻给service worker,service worker也得以发送新闻给页面,由于那个特点,能够将service worker作为中间纽带,使得多个域名依然子域名下的多少个页面能够随心所欲通讯。

此地是贰个小的页面之间通信demo

使用Service Worker

这段时间咱们有了polyfill,而且化解了HTTPS,让大家看见到底怎么用service worker。

动用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是一个InstallEvent对象,承继自ExtendableEvent,此中的waitUntil()方法接收叁个promise对象,直到那个promise对象成功resolve之后,才会继续运维service-worker.js。
caches是一个CacheStorage对象,使用open()方法张开一个缓存,缓存通过名称进行区分。
获得cache实例之后,调用addAll()方法缓存文件。

如此那般就将文件增添到caches缓存中了,想让浏览器选择缓存,还亟需拦截fetch事件

JavaScript

// 缓存图片 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; }); }) ) });

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的历程中,也碰着了黄金时代部分难题,下边是里面多个

怎么样注册和设置service worker

要安装service worker,你需求在你的页面上注册它。这些手续告诉浏览器你的service worker脚本在哪儿。

JavaScript

if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }).catch(function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }); }

1
2
3
4
5
6
7
8
9
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js').then(function(registration) {
    // Registration was successful
    console.log('ServiceWorker registration successful with scope: ',    registration.scope);
  }).catch(function(err) {
    // registration failed :(
    console.log('ServiceWorker registration failed: ', err);
  });
}

上边包车型客车代码检查service worker API是还是不是可用,固然可用,service worker /sw.js 被注册。

借使这几个service worker已经被登记过,浏览器会自行忽视下边包车型客车代码。

有二个亟待特意表明的是service worker文件的门路,你早晚注意到了在此个事例中,service worker文件被放在这里个域的根目录下,那象征service worker和网址同源。换句话说,那一个service work将会接到那些域下的具备fetch事件。假使本身将service worker文件注册为/example/sw.js,那么,service worker只能收到/example/路径下的fetch事件(例如: /example/page1/, /example/page2/)。

近日您能够到 chrome://inspect/#service-workers 检查service worker是否对你的网站启用了。

美高梅手机版 4

当service worker第黄金时代版被实现的时候,你也得以在chrome://serviceworker-internals中查看,它很有用,通过它可以最直观地熟悉service worker的生命周期,不过这个功能很快就会被移到chrome://inspect/#service-workers中。

你会意识这一个功效能够很方便地在二个模仿窗口中测量试验你的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,在调节和测量试验进程中时时等上风华正茂两分钟才会采用新的,相比较抓狂。

Service Worker的安装步骤

在页面上实现注册手续之后,让大家把集中力转到service worker的剧本里来,在此其间,大家要到位它的安装步骤。

在最大旨的事例中,你必要为install事件定义三个callback,并操纵怎样文件你想要缓存。

JavaScript

// The files we want to cache var urlsToCache = [ '/', '/styles/main.css', '/script/main.js' ]; // Set the callback for the install step self.addEventListener('install', function(event) { // Perform install steps });

1
2
3
4
5
6
7
8
9
10
11
// The files we want to cache
var urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];
 
// Set the callback for the install step
self.addEventListener('install', function(event) {
    // Perform install steps
});

在我们的install callback中,大家需求推行以下步骤:

  1. 开启叁个缓存
  2. 缓存大家的文本
  3. 支配是还是不是具备的能源是不是要被缓存

JavaScript

var CACHE_NAME = 'my-site-cache-v1'; var urlsToCache = [ '/', '/styles/main.css', '/script/main.js' ]; self.addEventListener('install', function(event) { // Perform install steps event.waitUntil( caches.open(CACHE_NAME) .then(function(cache) { console.log('Opened cache'); return cache.addAll(urlsToCache); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var CACHE_NAME = 'my-site-cache-v1';
var urlsToCache = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];
 
self.addEventListener('install', function(event) {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

地方的代码中,咱们透过caches.open张开大家内定的cache文件名,然后大家调用cache.addAll并传到大家的公文数组。那是通过大器晚成系列promise(caches.open 和 cache.addAll)达成的。event.waitUntil得到八个promise并行使它来取得安装耗费的年华以致是或不是安装成功。

倘使全数的文书都被缓存成功了,那么service worker就安装成功了。假若另外一个文书下载战败,那么安装步骤就能够失利。这些方法允许你依据于您自个儿钦定的装有能源,然则那意味你要求特别严厉地垄断哪些文件供给在安装步骤中被缓存。钦赐了太多的文书的话,就能够增添设置战败率。

上边只是一个简练的事例,你能够在install事件中举行其他操作依旧以致忽视install事件。

标题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 收藏 评论

美高梅手机版 5

什么样缓存和重返Request

您曾经设置了service worker,你现在能够回去您缓存的呼吁了。

当service worker被设置成功还要顾客浏览了另三个页面也许刷新了前段时间的页面,service worker将启幕收受到fetch事件。上面是二个例证:

JavaScript

self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return response if (response) { return response; } return fetch(event.request); } ) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
 
        return fetch(event.request);
      }
    )
  );
});

地点的代码里大家定义了fetch事件,在event.respondWith里,大家传入了四个由caches.match发生的promise.caches.match 查找request中被service worker缓存命中的response。

假定大家有三个命中的response,我们再次回到被缓存的值,不然大家回来一个实时从互联网央浼fetch的结果。那是三个特别轻易的事例,使用具备在install步骤下被缓存的能源。

若果大家想要增量地缓存新的呼吁,我们能够经过处理fetch央求的response并且增加它们到缓存中来达成,比方:

JavaScript

self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return response if (response) { return response; } // IMPORTANT: Clone the request. A request is a stream and // can only be consumed once. Since we are consuming this // once by cache and once by the browser for fetch, we need // to clone the response var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== 'basic') { return response; } // IMPORTANT: Clone the response. A response is a stream // and because we want the browser to consume the response // as well as the cache consuming the response, we need // to clone it so we have 2 stream. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
 
        // IMPORTANT: Clone the request. A request is a stream and
        // can only be consumed once. Since we are consuming this
        // once by cache and once by the browser for fetch, we need
        // to clone the response
        var fetchRequest = event.request.clone();
 
        return fetch(fetchRequest).then(
          function(response) {
            // Check if we received a valid response
            if(!response || response.status !== 200 || response.type !== 'basic') {
              return response;
            }
 
            // IMPORTANT: Clone the response. A response is a stream
            // and because we want the browser to consume the response
            // as well as the cache consuming the response, we need
            // to clone it so we have 2 stream.
            var responseToCache = response.clone();
 
            caches.open(CACHE_NAME)
              .then(function(cache) {
                cache.put(event.request, responseToCache);
              });
 
            return response;
          }
        );
      })
    );
});

代码里我们所做事情满含:

  1. 拉长一个callback到fetch伏乞的 .then 方法中
  2. 要是大家得到了贰个response,我们开展如下的检讨:
    1. 有限支撑response是有效的
    2. 检查response的景况是不是是200
    3. 保险response的品种是basic,那代表央浼作者是同源的,非同源(即跨域)的伸手也不能够被缓存。
  3. 借使大家通过了检讨,clone以此供给。这么做的原由是只要response是贰个Stream,那么它的body只好被读取叁回,所以大家得将它克隆出来,生机勃勃份发给浏览器,豆蔻梢头份发给缓存。

什么样创新二个Service Worker

你的service worker总有要求更新的那一天。当那一天光降的时候,你要求依照如下步骤来更新:

  1. 更新您的service worker的JavaScript文件
    1. 当客户浏览你的网址,浏览器尝试在后台下载service worker的剧本文件。只要服务器上的文件和当三步跳件有贰个字节差异,它们就被推断为索要更新。
  2. 立异后的service worker将起来运维,install event被重新触发。
  3. 在此个时刻节点上,当前页素不相识效的仍为老版本的service worker,新的servicer worker将跻身”waiting”状态。
  4. 当下页面被关闭之后,老的service worker进度被杀掉,新的servicer worker正式生效。
  5. 风流浪漫经新的service worker生效,它的activate事件被触发。

代码更新后,平时须求在activate的callback中实施二个管制cache的操作。因为您会要求排除掉以前旧的多少。我们在activate实际不是install的时候施行这几个操作是因为假如我们在install的时候立时实践它,那么照旧在运维的旧版本的数量就坏了。

从前大家只行使了三个缓存,叫做my-site-cache-v1,其实我们也可以使用多个缓存的,例如一个给页面使用,一个给blog的内容提交使用。这意味着,在install步骤里,我们可以创建两个缓存,pages-cache-v1和blog-posts-cache-v1,在activite步骤里,我们可以删除旧的my-site-cache-v1。

下边包车型大巴代码可以循环全数的缓存,删除掉全数不在白名单中的缓存。

JavaScript

self.addEventListener('activate', function(event) { var cacheWhitelist = ['pages-cache-v1', 'blog-posts-cache-v1']; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { return caches.delete(cacheName); } }) ); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
self.addEventListener('activate', function(event) {
 
  var cacheWhitelist = ['pages-cache-v1', 'blog-posts-cache-v1'];
 
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

拍卖边界和填坑

那风姿洒脱节内容相比较新,有大多待定细节。希望那蒸蒸日上节不慢就无需讲了(因为标准会管理这么些难题——译者注),不过现在,那个剧情仍然应该被提一下。

郑重声明:本文版权归美高梅163888所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。