Service Worker入门

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

正文以财富缓存为例,说美素佳儿(Friso)下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 fetch德姆o() { // fetch(url,
option)援助七个参数,option中能够设置header、body、method新闻fetch(U本田UR-VL).then(function(response) { // 通过promise
对象获得对应内容,并且将响应内容遵照json格式转成对象,json()方法调用之后回到的仍为promise对象
// 也能够把内容转形成arraybuffer、blob对象 return response.json();
}).then(function(json) { // 渲染页面 insertPhotos(json); }); }
fetch德姆o();

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卡塔 尔(英语:State of Qatar)完结的。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);
          }
        })
      );
    })
  );
});

拍卖边界和填坑

那风度翩翩节内容相比较新,有相当多待定细节。希望那后生可畏节超快就没有需求讲了(因为规范会管理那一个主题素材——译者注卡塔 尔(英语:State of Qatar),但是今后,这么些剧情照旧应该被提一下。

假若设置失败了,未有超高贵的秘籍拿到通报

固然三个worker被注册了,可是未有出今后chrome://inspect/#service-workers或chrome://serviceworker-internals,那么很可能因为异常而安装失败了,或者是产生了一个被拒绝的的promise给event.waitUtil。

要减轻那类难题,首先到 chrome://serviceworker-internals检查。打开开发者工具窗口准备调试,然后在你的install event代码中添加debugger;语句。这样,通过断点调试你更容易找到问题。

fetch()近日仅援救Service Workers

fetch登时帮忙在页面上运用了,不过如今的Chrome实现,它还只帮助service
worker。cache
API也将在在页面上被帮助,但是前段时间停止,cache也还只可以在service
worker中用。

fetch()的暗中同意参数

当您接收fetch,缺省级地区级,供给不会带上cookies等证据,要想带上的话,需求:

JavaScript

fetch(url, { credentials: ‘include’ })

1
2
3
fetch(url, {
  credentials: ‘include’
})

这么设计是有理由的,它比XH福特Explorer的在同源下暗许发送凭据,但跨域时放弃凭据的中规中矩要来得好。fetch的行为更像别的的COEnclaveS央浼,比方<img crossorigin>,它默认不发送cookies,除非你指定了<img crossorigin="use-credentials">.。

Non-COTiguanS私下认可不援助

暗中认可处境下,从第三方UENVISIONL跨域获得一个能源将会失利,除非对方扶植了COLacrosseS。你能够增加二个non-COPAJEROS选项到Request去幸免失利。代价是那样做会回来三个“不透明”的response,意味着你不可能搜查捕获这么些诉求毕竟是成功了大概诉讼失败了。

JavaScript

cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) { return new
Request(urlToPrefetch, { mode: ‘no-cors’ }); })).then(function() {
console.log(‘All resources have been fetched and cached.’); });

1
2
3
4
5
cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) {
  return new Request(urlToPrefetch, { mode: ‘no-cors’ });
})).then(function() {
  console.log(‘All resources have been fetched and cached.’);
});

fetch()不遵照30x重定向规范

噩运,重定向在fetch()中不会被触发,那是现阶段版本的bug;

管理响应式图片

img的srcset属性只怕<picture>标签会根据情况从浏览器或者网络上选择最合适尺寸的图片。

在service worker中,你想要在install步骤缓存三个图纸,你有以下两种选拔:

  1. 设置具备的<picture>元素或者将被请求的srcset属性。
  2. 设置单后生可畏的low-res版本图片
  3. 设置单风流倜傥的high-res版本图片

相比好的方案是2或3,因为风度翩翩旦把具有的图纸都给下载下来存着有一点点浪费内部存款和储蓄器。

只要你将low-res版本在install的时候缓存了,然后在页面加载的时候你想要尝试从网络上下载high-res的本子,然而如若high-res版本下载退步以来,就如故用low-res版本。那么些主张很好也值得去做,可是有二个难点:

生机勃勃经大家有上面几种图片:

Screen Density Width Height
1x 400 400
2x 800 800

HTML代码如下:

JavaScript

<img src=”image-src.png” srcset=”image-src.png 1x, image-2x.png 2x”
/>

1
<img src="image-src.png" srcset="image-src.png 1x, image-2x.png 2x" />

即使大家在一个2x的呈现形式下,浏览器会下载image-2x.png,假若大家离线,你能够读取在此之前缓存并重返image-src.png代替,假如早前它早就被缓存过。固然如此,由于今后的方式是2x,浏览器会把400X400的图纸展现成200X200,要幸免那一个主题素材即将要图片的样式上设置宽高。

JavaScript

<img src=”image-src.png” srcset=”image-src.png 1x, image-2x.png 2x”
style=”width:400px; height: 400px;” />

1
2
<img src="image-src.png" srcset="image-src.png 1x, image-2x.png 2x"
style="width:400px; height: 400px;" />

图片 6

<picture>标签情况更复杂一些,难度取决于你是如何创建和使用的,但是可以通过与srcset类似的思路去解决。

改变URL Hash的Bug

在M40版本中存在三个bug,它会让页面在改造hash的时候产生service
worker甘休职业。

您能够在此边找到越来越多相关的音讯: 

更加的多内容

此处有一点生死相依的文书档案能够参谋:

赢得帮忙

设若您遭遇麻烦,请在Stackoverflow上发帖询问,使用‘service-worker’标签,以便于大家及时跟进和尽只怕扶助您解除难题。

赞 2 收藏
评论

图片 5

admin

网站地图xml地图