>

连不上网

- 编辑:至尊游戏网站 -

连不上网

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

正文以资源缓存为例,说美素佳儿下service worker是什么样行事的。

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

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的运行周期

至尊游戏网站 3
上海教室是service worker生命周期,出处

图中得以看到,贰个service worker要经历以下进程:

  1.  安装

2.  激活,激活成功之后,打开chrome://inspect/#service-workers能够查阅到如今运维的service worker

至尊游戏网站 4

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

  2. 销毁,是不是销毁由浏览器决定,假使贰个service worker长期不接纳也许机器内部存款和储蓄器有数,则大概会销毁那些worker

试试看

您要求二个支撑 Service Worker 和 fetch API 的浏览器。甘休到本文编写时独有Chrome(手提式有线电话机版和桌面版)同一时候支持那三种 API(译者注:Opera 近年来也扶植那二者),但是 Firefox 不慢将在扶助了(在每一天更新的本子中曾经援救了),至尊游戏网站,除开 Safari 之外的有所浏览器也都在搜求。别的,service worker 只好登记在选取了 HTTPS 的网址上,theguardian.com 已经上马慢慢搬迁到 HTTPS,所以大家只可以在网址的 HTTPS 部分提供离线体验。就当前以来,大家选拔了 开垦者博客 作为我们用来测量检验的地点。所以只要您是在我们网址的 开垦者博客 部分阅读那篇小说的话,很幸运。

当你使用支持的浏览器访谈大家的 开荒者博客 中的页面的时候,一切就希图妥帖了。断开你的网络连接,然后刷新一下页面。如若您本身没规范尝试的话,能够看一下这段 演示录制(译者注:需梯子)。

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索罗德L).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支持。

工作规律

经过一段简单的 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 很感兴趣,想要领会越多内容的话,开荒者 MattGaunt(Chrome的忠实协助者)写了一篇特别详实地 介绍 Service Worker的文章。

打赏扶助本人翻译更加的多好小说,多谢!

打赏译者

message事件

页面和serviceWorker之间能够透过posetMessage()方法发送消息,发送的新闻可以因而message事件接收到。

那是三个双向的历程,页面能够发新闻给service worker,service worker也得以发送新闻给页面,由于这么些特点,可以将service worker作为中间纽带,使得一个域名如故子域名下的几个页面能够自由通讯。

这里是叁个小的页面之间通讯demo

打赏援助本身翻译更加的多好小说,谢谢!

至尊游戏网站 5

1 赞 收藏 评论

使用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.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的进程中,也超过了有些难点,上边是当中五个

有关小编:Erucy

至尊游戏网站 6

一度的SharePoint喵星工程师(近期还挂着微软MVP的名头),现在的Azure/.Net/MongoDB/Cordova/前端技术员,有时写小说 个人主页 · 作者的篇章 · 46 ·   

至尊游戏网站 7

主题材料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 收藏 评论

至尊游戏网站 8

本文由IT-综合发布,转载请注明来源:连不上网