大不列颠及英格兰联合王国卫报的秉性离线页面
分类:计算机知识

连不上网?英帝国卫报的性格离线页面是那般做的

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

本文由 伯乐在线 - Erucy 翻译,weavewillg 校稿。未经许可,禁止转发!
瑞典语出处:Oliver Ash。迎接参加翻译组。

小编们是怎么运用 service worker 来为 theguardian.com 营造多个自定义的离线页面。

图片 1

theguardian.com 的离线页面。插图:Oliver Ash

你正在朝着公司途中的地铁里,在四哥大上展开了 Guardian 应用。大巴被隧道包围着,但是这些应用能够健康运营,即便未有网络连接,你也能收获完全的功力,除了出示的内容恐怕有一点点旧。倘令你品尝在网址上也这么干,缺憾它完全无法加载:

图片 2

安卓版 Chrome 的离线页面

Chrome 中的这些彩蛋,很四人都不晓得》

Chrome 在离线页面上有个藏匿的游戏(桌面版上按空格键,手提式有线电话机版上点击那只恐龙),那有个别能缓慢解决一点你的抑郁。可是我们得以做得更加好。

Service workers 允许网址小编拦截自身站点的装有网络央求,那也就意味着大家得以提供完善的离线体验,就像是原生应用同样。在 Guardian 网址,大家近日上线了一个自定义的离线体验效果。当客户离线的时候,他们会见到二个富含Guardian 标记的页面,上边带有贰个简便的离线提醒,还也是有三个填字游戏,他们得以在等候互联网连接的时候玩玩那几个找点乐子。那篇博客解释了我们是怎么样创设它的,然则在始发在此以前,你能够先自个儿试试看。

运用 Service worker 创立一个特别轻巧的离线页面

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

本文由 伯乐在线 - 刘健超-J.c 翻译,艾凌风 校稿。未经许可,禁止转发!
塞尔维亚(Serbia)语出处:Dean Hume。招待参预翻译组。

让大家想像以下情状:我们那儿在一辆通往农村的列车里,用移动设备瞧着一篇很棒的文章。与此同一时候,当您点击“查看越来越多”的链接时,高铁遽然步入了隧道,导致运动装备失去了互连网,而 web 页面会彰显出类似以下的内容:

图片 3

那是卓殊让人衰颓的体验!幸运的是,web 开垦者们能经过一些新特点来立异那类的客户体验。笔者多年来直接在折腾 ServiceWorkers,它给 web 带来的点不清恐怕性总能给本人欢乐。Service Workers 的绝妙特质之一是同意你检查测量检验网络哀告的场景,并令你作出相应的响应。

在那篇小说里,小编盘算用此性情检查顾客的眼下互连网连接情形,假使没连接则赶回一个超级轻易的离线页面。固然那是二个相当基础的案例,但它能给你带来启发,让您精通运转并运转该特性是多么的简便!如若你没精晓过 Service Worker,作者建议您看看此 Github repo,驾驭越多相关的音讯。

在该案例先导前,让我们先简单地寻访它的办事流程:

  1. 在顾客第三回访问大家的页面时,大家会设置 ServiceWorker,并向浏览器的缓存增多大家的离线 HTML 页面
  2. 然后,若是顾客打算导航到另贰个 web 页面(同三个网址下),但此时已断网,那么咱们将赶回已被缓存的离线 HTML 页面
  3. 可是,借使客户图谋导航到其余多个 web 页面,而此刻网络已一而再,则能照常浏览页面

试试看

你供给三个帮忙 Service Worker 和 fetch API 的浏览器。截止到本文编写时唯有Chrome(手提式有线电话机版和桌面版)同有毛病间辅助那三种 API(译者注:Opera 最近也支持这两侧),然而 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 时,向缓存增加了离线页面。如若大家将代码分为几小块,可见到前几行代码中,作者为离线页面钦命了缓存版本和U揽胜极光L。假诺您的缓存有两样版本,那么你只需立异版本号就可以轻巧地清除缓存。在大意在第 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)改为 Offline。(译者注:若将节流设置为 Offline 没效果,则可经过关闭互连网或许经过360康宁警卫禁止 Chrome 访问互连网)

图片 4

假定您刷新页面,你应当能收看相应的离线页面!

图片 5

万一您只想大约地质衡量试该意义而不想写任何代码,那么你能够访谈作者已开立好的 demo。别的,上述总体代码能够在 Github repo 找到。

自个儿清楚用在此案例中的页面很简单,但您的离线页面则取决于你和睦!要是你想深刻该案例的从头到尾的经过,你可认为离线页面增添缓存破坏( cache busting),如: 此案例。

做事原理

通过一段轻便的 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 功用(用于转移互连网伏乞),如下所示:

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。那是三个轻量的台本,能让您更轻便地利用离线作用。

打赏匡助本人翻译越来越多好文章,谢谢!

打赏译者

本文由威尼斯手机娱乐官网发布于计算机知识,转载请注明出处:大不列颠及英格兰联合王国卫报的秉性离线页面

上一篇:没有了 下一篇:没有了
猜你喜欢
热门排行
精彩图文