连不上网,创建一个非常简单的离线页面

连不上网?大不列颠及苏格兰联合王国卫报的性情离线页面是那样做的

2015/11/20 · HTML5 · Service
Worker,
离线页面

本文由 伯乐在线 –
Erucy
翻译,weavewillg
校稿。未经许可,禁绝转发!
乌克兰语出处:Oliver
Ash。接待参加翻译组。

我们是怎样使用 service worker 来为 theguardian.com
创设一个自定义的离线页面。

图片 1

theguardian.com 的离线页面。插图:奥利弗 Ash

您正在朝着公司途中的大巴里,在手提式有线话机上开采了
Guardian
应用。客车被隧道包围着,但是那几个利用能够平常运营,就算未有网络连接,你也能获取完全的效用,除了呈现的内容恐怕有一点旧。要是您品味在网址上也这么干,缺憾它完全无法加载:

图片 2

安卓版 Chrome 的离线页面

Chrome 中的这一个彩蛋,很四个人都不领悟》

Chrome
在离线页面上有个暗藏的游玩(桌面版上按空格键,手提式有线电话机版上点击那只恐龙卡塔 尔(阿拉伯语:قطر‎,那多少能缓和一点你的愤懑。不过大家得以做得越来越好。

Service
workers
允许网址笔者拦截自个儿站点的富有互连网诉求,那也就代表我们能够提供全面包车型客车离线体验,就好像原生应用相符。在
Guardian
网址,大家多年来上线了三个自定义的离线体验效果。当客商离线的时候,他们拜谒到二个包蕴Guardian
标志的页面,上边带有七个概括的离线提醒,还应该有三个填字游戏,他们得以在等候互连网连接的时候玩玩这一个找点乐子。那篇博客解释了大家是怎么创设它的,可是在开班早先,你可以先自身尝试看。

选用 Service worker 创造叁个非常轻易的离线页面

2016/06/07 · JavaScript
· 1 评论 · Service
Worker

本文由 伯乐在线 –
刘健超-J.c
翻译,艾凌风
校稿。未经许可,禁止转发!
德文出处:Dean
Hume。迎接插足翻译组。

让大家想像以下场景:大家那儿在生机勃勃辆通往乡村的高铁上,用运动道具望着黄金时代篇很棒的随笔。与此同一时间,当您点击“查看更多”的链接时,高铁乍然步入了隧道,引致运动器材失去了互联网,而
web 页面会显示出相似以下的源委:

图片 3

那是分外令人颓废的心得!幸运的是,web
开辟者们能透过有个别新性格来更正这类的客商体验。作者方今直接在折腾 ServiceWorkers,它给 web 带给的数不完恐怕性总能给自个儿惊奇。Service Workers
的突出特质之一是同意你检验互连网央求的景色,并令你作出相应的响应。

在这里篇小说里,笔者打算用此特性检查客商的一时一刻网络连接情况,假设没连接则赶回三个最好轻巧的离线页面。固然那是一个丰裕幼功的案例,但它能给您带给启迪,令你了然运营并运转该性格是多么的总结!假设您没掌握过
Service Worker,作者建议你看看此 Github
repo,驾驭越多相关的消息。

在本案例开端前,让大家先简单地拜望它的做事流程:

  1. 在客户第三回访谈大家的页面时,大家会设置 ServiceWorker,并向浏览器的缓存增多大家的离线 HTML 页面
  2. 接下来,要是客户计划导航到另叁个 web
    页面(同一个网址下卡塔尔,但此刻已断网,那么大家将赶回已被缓存的离线
    HTML 页面
  3. 然则,假若顾客计划导航到别的几个 web
    页面,而此刻互联网已延续,则能照常浏览页面

Service Worker入门

2015/03/26 · JavaScript
· Service Worker

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

  • 十年踪迹]()   

原生App具备Web应用普通所不有所的富离线体验,准期的默不做声更新,新闻布告推送等效果。而新的Serviceworkers标准让在Web App上保有那么些功能成为恐怕。

试试看

你必要一个支撑 Service
Worker 和 fetch
API 的浏览器。截至到本文编写时唯有Chrome(手提式有线话机版和桌面版卡塔尔国同不经常间扶助那三种 API(译者注:Opera
近来也支撑这两个卡塔 尔(英语:State of Qatar),然则 Firefox
比十分的快将要扶持了(在每日更新的本子中生机勃勃度支撑了卡塔尔国,除了 Safari
之外的富有浏览器也都在尝试。其它,service worker 只好登记在行使了
HTTPS 的网址上,theguardian.com
已经起来稳步搬迁到 HTTPS,所以大家必须要在网址的 HTTPS
部分提供离线体验。就当下的话,我们筛选了 开拓者博客 作为大家用来测验的地点。所以要是您是在大家网址的 开采者博客 部分阅读那篇小说的话,很幸运。

当你利用辅助的浏览器访谈大家的 开采者博客 中的页面包车型客车时候,一切就希图妥帖了。断开你的网络连接,然后刷新一下页面。要是你和谐没标准尝试的话,可以看一下这段 示范摄像(译者注:需梯子)。

让我们初步吧

若果你有以下 HTML 页面。那即便那个基本功,但能给您完整思路。

XHTML

<!DOCTYPE html>

1
<!DOCTYPE html>

进而,让大家在页面里登记 Service Worker,这里仅创立了该对象。向正要的
HTML 里增多以下代码。

JavaScript

<script> // Register the service worker // 注册 service worker if
(‘serviceWorker’ in navigator) {
navigator.serviceWorker.register(‘/service-worker.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); }); }
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<script>
// Register the service worker
// 注册 service worker
if (‘serviceWorker’ in navigator) {
    navigator.serviceWorker.register(‘/service-worker.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);
   });
}
</script>

下一场,我们须要创建 Service Worker 文件并将其取名字为‘service-worker.js‘。大家策动用这几个 Service Worker
拦截任何网络央求,以此检查互联网的连接性,并依据检查结果向客商重回最符合的剧情。

JavaScript

‘use strict’; var cacheVersion = 1; var currentCache = { offline:
‘offline-cache’ + cacheVersion }; const offlineUrl =
‘offline-page.html’; this.addEventListener(‘install’, event => {
event.waitUntil( caches.open(currentCache.offline).then(function(cache)
{ return cache.addAll([ ‘./img/offline.svg’, offlineUrl ]); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
‘use strict’;
 
var cacheVersion = 1;
var currentCache = {
  offline: ‘offline-cache’ + cacheVersion
};
const offlineUrl = ‘offline-page.html’;
 
this.addEventListener(‘install’, event => {
  event.waitUntil(
    caches.open(currentCache.offline).then(function(cache) {
      return cache.addAll([
          ‘./img/offline.svg’,
          offlineUrl
      ]);
    })
  );
});

在地点的代码中,大家在安装 Service Worker
时,向缓存增加了离线页面。借使我们将代码分为几小块,可看出前几行代码中,我为离线页面内定了缓存版本和UTiguanL。若是你的缓存有两样版本,那么您只需修改版本号就可以轻易地解除缓存。在大约在第
12
行代码,笔者向这几个离线页面及其能源(如:图片卡塔尔发出要求。在获得成功的响应后,大家将离线页面和血脉相像能源丰硕到缓存。

现行反革命,离线页面已存进缓存了,大家可在急需的时等候检查索它。在同一个 ServiceWorker 中,大家须求对无网络时重临的离线页面增加相应的逻辑代码。

JavaScript

this.addEventListener(‘fetch’, event => { // request.mode = navigate
isn’t supported in all browsers // request.mode = naivgate
并未得到全体浏览器的帮忙 // so include a check for Accept: text/html
header. // 因而对 header 的 Accept:text/html 举行核准 if
(event.request.mode === ‘navigate’ || (event.request.method === ‘GET’ &&
event.request.headers.get(‘accept’).includes(‘text/html’))) {
event.respondWith( fetch(event.request.url).catch(error => { //
Return the offline page // 重回离线页面 return caches.match(offlineUrl);
}) ); } else{ // Respond with everything else if we can //
重回任何大家能回到的事物 event.respondWith(caches.match(event.request)
.then(function (response) { return response || fetch(event.request); })
); } });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
this.addEventListener(‘fetch’, event => {
  // request.mode = navigate isn’t supported in all browsers
  // request.mode = naivgate 并没有得到所有浏览器的支持
  // so include a check for Accept: text/html header.
  // 因此对 header 的 Accept:text/html 进行核实
  if (event.request.mode === ‘navigate’ || (event.request.method === ‘GET’ && event.request.headers.get(‘accept’).includes(‘text/html’))) {
        event.respondWith(
          fetch(event.request.url).catch(error => {
              // Return the offline page
              // 返回离线页面
              return caches.match(offlineUrl);
          })
    );
  }
  else{
        // Respond with everything else if we can
        // 返回任何我们能返回的东西
        event.respondWith(caches.match(event.request)
                        .then(function (response) {
                        return response || fetch(event.request);
                    })
            );
      }
});

为了测量试验该效能,你能够运用 Chrome
内置的开辟者工具。首先,导航到您的页面,然后借使设置上了 ServiceWorker,就开垦 Network 标签并将节流(throttling卡塔 尔(英语:State of Qatar)改为
Offline。(译者注:若将节流设置为 Offline
没意义,则可透过关闭互连网或许通过360安然依然警卫禁绝 Chrome 访谈互联网卡塔尔

图片 4

设若你刷新页面,你应有能来六柱预测应的离线页面!

图片 5

假定你只想大约地质衡量试该意义而不想写任何代码,那么你可以访谈笔者已创立好的
demo。其它,上述任何代码能够在
Github repo 找到。

本人理解用在那案例中的页面很简短,但你的离线页面则决定于你自个儿!要是你想深切该案例的内容,你可感觉离线页面增添缓存破坏(
cache busting卡塔尔国,如:
此案例。

Service Worker 是什么?

一个 service worker
是风流洒脱段运转在浏览器后台进度里的脚本,它独立于当下页面,提供了这一个没有需求与web页面人机联作的效益在网页背后悄悄实行的力量。在明天,基于它能够兑现音信推送,静默更新甚至地理围栏等劳动,可是当前它首先要有所的机能是阻止和拍卖互连网央求,包罗可编制程序的响应缓存管理。

为啥说那么些API是一个百般棒的API呢?因为它使得开拓者可以支撑非常好的离线体验,它授予开荒者完全调控离线数据的力量。

在service worker建议此前,其它八个提供开垦者离线体验的API叫做App
Cache。不过App
Cache有个别局限性,比如它能够超轻便地解决单页应用的难点,不过在多页应用上会很劳累,而瑟维斯workers的现身正是为了清除App Cache的痛点。

上边详细说一下service worker有如何须要注意的地点:

  • 它是JavaScript
    Worker,所以它不能够一直操作DOM。不过service
    worker能够通过postMessage与页面之间通讯,把信息通告给页面,即便必要的话,让页面本身去操作DOM。
  • Serviceworker是三个可编制程序的互连网代理,允许开荒者调整页面上拍卖的互连网伏乞。
  • 在不被选择的时候,它会和谐终止,而当它再也被用到的时候,会被重复激活,所以你不可能依赖于service
    worker的onfecth和onmessage的管理函数中的全局状态。假诺你想要保存一些长久化的新闻,你能够在service
    worker里使用IndexedDB API。
  • Serviceworker大量使用promise,所以生机勃勃旦你不打听如何是promise,这您要求先读书这篇文章。

职业规律

透过生机勃勃段简单的
JavaScript,大家得以提醒浏览器在客户访谈页面包车型客车时候立即登记大家相依为命的
service worker。近日支撑 service worker
的浏览器非常少,所认为了防止不当,大家供给选择个性检查评定。

JavaScript

if (navigator.serviceWorker) {
navigator.serviceWorker.register(‘/service-worker.js’); }

1
2
3
if (navigator.serviceWorker) {
    navigator.serviceWorker.register(‘/service-worker.js’);
}

Service worker
安装事件的大器晚成局地,我们得以选取 新的缓存
API 来缓存我们网站中的各样内容,例如
HTML、CSS 和
JavaScript:

JavaScript

var staticCacheName = ‘static’; var version = 1; function updateCache()
{ return caches.open(staticCacheName + version) .then(function (cache) {
return cache.addAll([ ‘/offline-page.html’, ‘/assets/css/main.css’,
‘/assets/js/main.js’ ]); }); }; self.addEventListener(‘install’,
function (event) { event.waitUntil(updateCache()); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var staticCacheName = ‘static’;
var version = 1;
 
function updateCache() {
    return caches.open(staticCacheName + version)
        .then(function (cache) {
            return cache.addAll([
                ‘/offline-page.html’,
                ‘/assets/css/main.css’,
                ‘/assets/js/main.js’
            ]);
        });
};
 
self.addEventListener(‘install’, function (event) {
    event.waitUntil(updateCache());
});

当安装到位后,service worker
能够监听和操纵 fetch
事件,让大家能够完全调整之后网址中生出的持有网络央求。

JavaScript

self.addEventListener(‘fetch’, function (event) {
event.respondWith(fetch(event.request)); });

1
2
3
self.addEventListener(‘fetch’, function (event) {
    event.respondWith(fetch(event.request));
});

在那处大家有很利索的空中能够表明,例如下边那个骨节眼,能够经过代码来生成大家自己的央浼响应:

JavaScript

self.addEventListener(‘fetch’, function (event) { var response = new
Response(‘<h1>Hello, World!</h1>’, { headers: {
‘Content-Type’: ‘text/html’ } }); event.respondWith(response); });

1
2
3
4
5
self.addEventListener(‘fetch’, function (event) {
    var response = new Response(‘&lt;h1&gt;Hello, World!&lt;/h1&gt;’,
        { headers: { ‘Content-Type’: ‘text/html’ } });
    event.respondWith(response);
});

还会有这几个,借使在缓存中找到了央求相应的缓存,大家得以向来从缓存中回到它,借使没找到的话,再经过网络获取响应内容:

JavaScript

self.addEventListener(‘fetch’, function (event) { event.respondWith(
caches.match(event.request) .then(function (response) { return response
|| fetch(event.request); }) ); });

1
2
3
4
5
6
7
8
self.addEventListener(‘fetch’, function (event) {
    event.respondWith(
        caches.match(event.request)
            .then(function (response) {
                return response || fetch(event.request);
            })
    );
});

那正是说大家怎样利用那么些效应来提供离线体验呢?

首先,在 service worker
安装进度中,大家供给把离线页面需求的 HTML 和能源文件通过 service worker
缓存下来。在缓存中,大家加载了友好费用的 填字游戏 的
React应用 页面。之后,我们会阻止全部访问theguardian.com
互连网央求,满含网页、以致页面中的财富文件。管理那些央浼的逻辑大约如下:

  1. 当我们质量评定到传播央浼是指向我们的 HTML
    页面时,大家连年会想要提供最新的故事情节,所以我们会尝试把这些要求通过网络发送给服务器。

    1. 当我们从服务器获得了响应,就能够直接回到这一个响应。
    2. 豆蔻梢头经网络乞请抛出了要命(譬喻因为客商掉线了卡塔 尔(阿拉伯语:قطر‎,大家捕获那个这一个,然后使用缓存的离线
      HTML 页面作为响应内容。
  2. 不然,当大家检查测量检验到乞请的不是 HTML
    的话,我们会从缓存中搜索响应的伸手内容。

    1. 假设找到了缓存内容,大家能够直接重回缓存的源委。
    2. 要不,大家会尝试把这几个诉求通过网络发送给服务器。

在代码中,咱们选择了 新的缓存
API(它是 Service Worker API 的一片段卡塔尔国以至
fetch
功效(用于转移互连网乞求卡塔 尔(英语:State of Qatar),如下所示:

JavaScript

var doesRequestAcceptHtml = function (request) { return
request.headers.get(‘Accept’) .split(‘,’) .some(function (type) { return
type === ‘text/html’; }); }; self.addEventListener(‘fetch’, function
(event) { var request = event.request; if
(doesRequestAcceptHtml(request)) { // HTML pages fallback to offline
page event.respondWith( fetch(request) .catch(function () { return
caches.match(‘/offline-page.html’); }) ); } else { // Default fetch
behaviour // Cache first for all other requests event.respondWith(
caches.match(request) .then(function (response) { return response ||
fetch(request); }) ); } });

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
var doesRequestAcceptHtml = function (request) {
    return request.headers.get(‘Accept’)
        .split(‘,’)
        .some(function (type) { return type === ‘text/html’; });
};
 
self.addEventListener(‘fetch’, function (event) {
    var request = event.request;
    if (doesRequestAcceptHtml(request)) {
        // HTML pages fallback to offline page
        event.respondWith(
            fetch(request)
                .catch(function () {
                    return caches.match(‘/offline-page.html’);
                })
        );
    } else {
        // Default fetch behaviour
        // Cache first for all other requests
        event.respondWith(
            caches.match(request)
                .then(function (response) {
                    return response || fetch(request);
                })
        );
    }
});

就只供给那样多!theguardian.com
上的 有着代码都以在 GitHub
上开源 的,所以您能够去那儿查看大家的
service worker
的完好版本,只怕直接从生育蒙受上访谈

大家有丰硕的理由为那么些新的浏览器本事欢呼喝彩,因为它能够用来让你的网址像明天的原生应用相近,具有完美的离线体验。以往当
theguardian.com 完全迁移到 HTTPS
之后,离线页面包车型客车要紧性会明显扩展,我们能够提供进一层周密的离线体验。设想一下您在上下班途中网络非常差的时候访谈theguardian.com,你会见到特地为你订制的性格化内容,它们是在您后面访谈网址时由浏览器缓存下来的。它在装置进度中也不会发出任何不便,你所供给的只是访谈那个网站而已,不像原生应用,还索要客商有多个运用商铺的账号工夫安装。Serviceworker
同样能够帮忙大家进步网站的加载速度,因为网址的框架能够被保障地缓存下来,就像原生应用相通。

若是你对 service worker
很感兴趣,想要理解更加多内容的话,开辟者 马特Gaunt(Chrome的赤血丹心帮助者卡塔尔国写了黄金年代篇尤其详细地 介绍 Service
Worker的文章。

打赏支持本人翻译愈来愈多好文章,感激!

打赏译者

展开阅读

别的,还会有多少个很棒的离线效率案例。如:Guardian 创设了多个全部 crossword
puzzle(填字游戏卡塔尔的离线
web 页面 –
因而,尽管等待互连网重连时(即已在离线状态下卡塔尔,也能找到一点野趣。我也引入看看
Google Chrome Github
repo,它含有了成都百货上千不风流倜傥的
Service Worker 案例 – 在那之中有的行使案例也在这里!

而是,倘让你想跳过上述代码,只是想大致地通过二个库来管理有关操作,那么本身推荐你看看
UpUp。那是叁个轻量的脚本,能让你更自在地接受离线成效。

打赏协助本人翻译越多好小说,多谢!

打赏译者

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初次安装的生命周期:

图片 6

打赏帮助自个儿翻译越来越多好文章,谢谢!

图片 7

1 赞 收藏
评论

打赏协理作者翻译越来越多好文章,感激!

任选大器晚成种支付方式

图片 8
图片 9

1 赞 3 收藏 1
评论

在大家伊始写码以前

从这个项目地址拿到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打听最好实行。

有关小编:Erucy

图片 10

现已的SharePoint喵星技师(一时还挂着微软MVP的名头卡塔 尔(英语:State of Qatar),今后的Azure/.Net/MongoDB/科尔多瓦/前端程序员,不经常写小说
个人主页 ·
作者的篇章 ·
46 ·
  

图片 11

关于小编:刘健超-J.c

图片 12

前端,在路上…
个人主页 ·
笔者的文章 ·
19 ·
    

图片 11

使用Service Worker

今天我们有了polyfill,並且解决了HTTPS,让我们看看毕竟怎么用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是否对你的网站启用了。

图片 14

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

您会意识这几个职能能够很有益于地在三个模拟窗口中测量试验你的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事件。

怎么着缓存和再次回到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’
})

像这种类型设计是有理由的,它比XHWrangler的在同源下暗许发送凭据,但跨域时放任凭据的准绳要来得好。fetch的作为更像其它的CO猎豹CS6S央求,比如<img crossorigin>,它默认不发送cookies,除非你指定了<img crossorigin="use-credentials">.。

Non-CO锐界S暗中同意不援救

默许意况下,从第三方U奔驰G级L跨域获得三个能源将会失败,除非对方援助了CO冠道S。你能够增添三个non-CO奔驰M级S选项到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;" />

图片 15

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

改变URL Hash的Bug

在M40版本中留存三个bug,它会让页面在更改hash的时候形成service
worker甘休专业。

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

越多内容

这里有部分相关的文档能够仿效:

获得支持

假如您遇见麻烦,请在Stackoverflow上发帖询问,使用‘service-worker’标签,以便于大家立时跟进和不择手腕扶助你消除难点。

赞 2 收藏
评论

图片 11

发表评论

电子邮件地址不会被公开。 必填项已用*标注