service worker是一段脚本

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); }); } 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扶持。

做事原理

通过一段轻便的 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的文章。

打赏辅助作者翻译愈来愈多好小说,感激!

打赏译者

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对象,承接自Extendable伊夫nt,此中的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的长河中,也遇到了部分难点,上边是里面多个

至于小编: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

本文由金莎娱乐场官方网站发布于关于计算机,转载请注明出处:service worker是一段脚本

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。