连不上网,入门教程

Service Worker初体验

2016/01/06 · JavaScript
· Service Worker

连不上网,入门教程。原稿出处: AlloyTeam   

在2016年,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.  … …

正文以资源缓存为例,说爱他美(Beingmate)下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
网站,大家近日上线了3个自定义的离线体验效果。当用户离线的时候,他们会看到二个含有
Guardian
标识的页面,下边带有多少个简单的离线提醒,还有贰个填字游戏,他们得以在守候互联网连接的时候玩玩那么些找点乐子。这篇博客解释了我们是什么营造它的,但是在初阶以前,你可以先本身摸索看。

Service Worker入门

2015/03/26 · JavaScript
· Service Worker

原著出处: Matt
Gaunt连不上网,入门教程。   译文出处:[w3ctech

  • 十年踪迹]()   

原生App拥有Web应用一般所不具有的富离线体验,定时的沉默寡言更新,音信通告推送等功用。而新的Serviceworkers标准让在Web App上存有这几个意义成为大概。

渐进式Web应用(PWA)入门教程(下)

2018/05/25 · 基本功技术 ·
PWA

初稿出处: Craig
Buckler   译文出处:葡萄城控件   

上篇小说我们对渐进式Web应用(PWA)做了部分基本的介绍。

渐进式Web应用(PWA)入门教程(上)

在这一节中,大家将介绍PWA的规律是何等,它是何许初步工作的。

生命周期

先来看一下2个service worker的周转周期

皇家赌场手机版 3
上海教室是service
worker生命周期,出处

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

  1.  安装

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

皇家赌场手机版 4

  1. 监听fetch和message事件,上边三种事件会进展简短描述

  2. 销毁,是还是不是销毁由浏览器决定,假如2个service
    worker长时间不采纳依然机器内部存款和储蓄器有数,则大概会销毁这么些worker

试试看

你必要贰个支撑 Service
Worker 和 fetch
API 的浏览器。结束到本文编写时只有Chrome(手提式有线电话机版和桌面版)同时帮助那两种 API(译者注:Opera
近来也支撑那两者),但是 Firefox
极快就要协理了(在天天更新的本子中曾经支撑了),除此之外 Safari
之外的有着浏览器也都在尝试。别的,service worker 只可以登记在使用了
HTTPS 的网站上,theguardian.com
已经上马稳步搬迁到 HTTPS,所以大家只幸亏网站的 HTTPS
部分提供离线体验。就当前以来,大家选用了 开发者博客 作为大家用来测试的地点。所以一旦你是在我们网站的 开发者博客 部分阅读那篇作品的话,很幸运。

当您选用支持的浏览器访问大家的 开发者博客 中的页面包车型大巴时候,一切就准备稳当了。断开你的互联网连接,然后刷新一下页面。借使你协调没条件尝试的话,能够看一下那段 以身作则录像(译者注:需梯子)。

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是2个可编制程序的网络代理,允许开发者控制页面上拍卖的网络请求。
  • 在不被选择的时候,它会融洽终止,而当它再度被用到的时候,会被再度激活,所以您不能够凭借于service
    worker的onfecth和onmessage的处理函数中的全局状态。如果你想要保存一些持久化的音讯,你能够在service
    worker里使用IndexedDB API。
  • Serviceworker多量使用promise,所以一旦你不打听如何是promise,那您需求先读书这篇文章。

第一步:使用HTTPS

渐进式Web应用程序需求使用HTTPS连接。固然使用HTTPS会让您服务器的支出变多,但选取HTTPS能够让你的网站变得更安全,HTTPS网站在谷歌上的排名也会更靠前。

鉴于Chrome浏览器会默许将localhost以及127.x.x.x地址视为测试地方,所以在本示例中您并不必要开启HTTPS。此外,出于调节和测试指标,您能够在开行Chrome浏览器的时候利用以下参数来关闭其对网站HTTPS的反省:

  • –user-data-dir
  • –unsafety-treat-insecure-origin-as-secure

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 fetchDemo() { // fetch(url,
option)辅助多个参数,option中能够安装header、body、method信息fetch(UENVISIONL).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,你碰面到专门为您订制的个性化内容,它们是在您后边访问网站时由浏览器缓存下来的。它在安装进度中也不会发生其他辛勤,你所须求的只是访问这一个网站而已,不像原生应用,还须要用户有3个使用商店的账号才能设置。Serviceworker
同样能够扶助大家升高网站的加载速度,因为网站的框架能够被有限支持地缓存下来,就如原生应用相同。

如若你对 service worker
很感兴趣,想要理解愈来愈多内容的话,开发者 马特Gaunt(Chrome的忠诚协助者)写了一篇越发详细地 介绍 Service
Worker的文章。

打赏扶助小编翻译更加多好小说,多谢!

打赏译者

Service Worker的生命周期

瑟维斯 worker拥有三个完全部独用立于Web页面包车型客车生命周期。

要让三个service
worker在您的网站上生效,你要求先在你的网页中登记它。注册一个service
worker之后,浏览器会在后台默默运转七个service worker的安装进度。

在安装进程中,浏览器会加载并缓存一些静态财富。如果拥有的文书被缓存成功,service
worker就设置成功了。假设有其它文件加载或缓存战败,那么安装进度就会破产,service
worker就不可能被激活(也即没能安装成功)。假如发生那样的题材,别担心,它会在下次再品尝安装。

当安装到位后,service
worker的下一步是激活,在这一品级,你还是可以够提高3个service
worker的本子,具体内容我们会在后面讲到。

在激活之后,service
worker将接管全体在本身管辖域范围内的页面,不过如果1个页面是刚刚注册了service
worker,那么它这贰回不会被接管,到下二回加载页面包车型客车时候,service
worker才会生效。

当service
worker接管了页面之后,它可能有三种情形:要么被终止以节约内部存款和储蓄器,要么会处理fetch和message事件,那七个事件分别发生于几个互联网请求出现照旧页面上发送了1个音讯。

下图是三个简化了的service worker初次安装的生命周期:

皇家赌场手机版 5

第1步:成立二个应用程序清单(Manifest)

应用程序清单提供了和当前渐进式Web应用的连带消息,如:

  • 应用程序名
  • 描述
  • 怀有图片(包蕴主显示器图标,运转显示器页面和用的图样恐怕网页上用的图样)

精神上讲,程序清单是页面上用到的图标和大旨等财富的元数据。

程序清单是二个位于您使用根目录的JSON文件。该JSON文件再次回到时务必抬高Content-Type: application/manifest+json 或者 Content-Type: application/jsonHTTP头消息。程序清单的文件名不限,在本文的示范代码中为manifest.json

{ “name” : “PWA Website”, “short_name” : “PWA”, “description” : “An
example PWA website”, “start_url” : “/”, “display” : “standalone”,
“orientation” : “any”, “background_color” : “#ACE”, “theme_color” :
“#ACE”, “icons”: [ { “src” : “/images/logo/logo072.png”, “sizes” :
“72×72”, “type” : “image/png” }, { “src” : “/images/logo/logo152.png”,
“sizes” : “152×152”, “type” : “image/png” }, { “src” :
“/images/logo/logo192.png”, “sizes” : “192×192”, “type” : “image/png” },
{ “src” : “/images/logo/logo256.png”, “sizes” : “256×256”, “type” :
“image/png” }, { “src” : “/images/logo/logo512.png”, “sizes” :
“512×512”, “type” : “image/png” } ] }

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
{
  "name"              : "PWA Website",
  "short_name"        : "PWA",
  "description"       : "An example PWA website",
  "start_url"         : "/",
  "display"           : "standalone",
  "orientation"       : "any",
  "background_color"  : "#ACE",
  "theme_color"       : "#ACE",
  "icons": [
    {
      "src"           : "/images/logo/logo072.png",
      "sizes"         : "72×72",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo152.png",
      "sizes"         : "152×152",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo192.png",
      "sizes"         : "192×192",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo256.png",
      "sizes"         : "256×256",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo512.png",
      "sizes"         : "512×512",
      "type"          : "image/png"
    }
  ]
}

程序清单文件建立完今后,你必要在种种页面上引用该文件:

<link rel=”manifest” href=”/manifest.json”>

1
<link rel="manifest" href="/manifest.json">

以下属性在程序清单中时常选取,介绍表明如下:

  • name: 用户观察的行使名称
  • short_name: 应用短名称。当显示采用名称的地点不够时,将动用该名称。
  • description: 运用描述。
  • start_url: 动用开头路径,相对路径,暗中同意为/。
  • scope: U卡宴L范围。比如:假若你将“/app/”设置为U酷路泽L范围时,那些动用就会间接在这些目录中。
  • background_color: 欢迎页面包车型客车背景颜色和浏览器的背景颜色(可选)
  • theme_color: 利用的大旨颜色,一般都会和背景颜色一样。这些设置决定了利用怎样展示。
  • orientation: 事先旋转方向,可选的值有:any, natural, landscape,
    landscape-primary, landscape-secondary, portrait, portrait-primary,
    and portrait-secondary
  • display: 展现格局——fullscreen(无Chrome),standalone(和原生应用相同),minimal-ui(最小的一套UI控件集)只怕browser(最古老的运用浏览器标签突显)
  • icons: 二个包罗全部图片的数组。该数组中各种元素包蕴了图片的UPAJEROL,大小和项目。

message事件

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

那是一个双向的长河,页面能够发音讯给service worker,service
worker也足以发送新闻给页面,由于那一个性情,能够将service
worker作为中间纽带,使得二个域名还是子域名下的五个页面能够轻易通讯。

那边是2个小的页面之间通讯demo

打赏补助作者翻译越来越多好作品,多谢!

皇家赌场手机版 6

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打听最佳实践。

其三步:创造1个 Service Worker

Service Worker
是1个可编制程序的服务器代理,它能够阻挡或然响应互联网请求。Service Worker
是身处应用程序根目录的一个个的JavaScript文件。

你供给在页面对应的JavaScript文件中注册该ServiceWorker:

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

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

倘诺你不要求离线的相干职能,您能够只创建贰个 /service-worker.js文件,这样用户就能够直接设置您的Web应用了!

ServiceWorker那个概念大概相比难懂,它其实是三个做事在别的线程中的标准的Worker,它不得以访问页面上的DOM成分,没有页面上的API,但是足以阻挡全部页面上的网络请求,包括页面导航,请求财富,Ajax请求。

上边正是利用全站HTTPS的重庆大学缘由了。倘若你没有在你的网站中运用HTTPS,贰个第①方的台本就足以从此外的域名注入他协调的瑟维斯Worker,然后篡改全体的央浼——那毋庸置疑是极度危险的。

Service Worker 会响应八个事件:install,activate和fetch。

动用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是二个Install伊芙nt对象,继承自Extendable伊夫nt,当中的waitUntil()方法接收一个promise对象,直到这么些promise对象成功resolve之后,才会持续运转service-worker.js。
caches是3个CacheStorage对象,使用open()方法打开3个缓存,缓存通过名称进行区分。
取得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

皇家赌场手机版 7

早已的SharePoint喵星程序猿(一时还挂着微软MVP的名头),以往的Azure/.Net/MongoDB/Cordova/前端程序猿,偶尔写小说
个人主页 ·
笔者的篇章 ·
46 ·
  

皇家赌场手机版 8

使用Service Worker

未来我们有了polyfill,并且解决了HTTPS,让大家看看毕竟怎么用service
worker。

Install事件

该事件将在选拔设置到位后触发。大家一般在此间运用Cache
API缓存一些不可或缺的文本。

首先,我们须要提供如下配置

  1. 缓存名称(CACHE)以及版本(version)。应用能够有七个缓存存款和储蓄,可是在利用时只会选用在那之中一个缓存存储。每当缓存存款和储蓄有变动时,新的版本号将会钦点到缓存存储中。新的缓存存款和储蓄将会作为当前的缓存存款和储蓄,在此之前的缓存存款和储蓄将会被作废。
  2. 一个离线的页面地址(offlineU本田UR-VL):当用户访问了前头从没访问过的位置时,该页面将会议及展览示。
  3. 3个分包了独具必须文件的数组,包蕴保持页面符合规律职能的CSS和JavaScript。在本示例中,笔者还添加了主页和logo。当有例外的ULANDL指向同一个能源时,你也能够将那么些U福睿斯L分别写到那个数组中。offlineULacrosseL将会参加到那么些数组中。
  4. 大家也能够将一部分非供给的缓存文件(installFilesDesirable)。那么些文件在设置进度准将会被下载,但只要下载退步,不会接触安装失利。

// 配置文件 const version = ‘1.0.0’, CACHE = version + ‘::PWAsite’,
offlineU普拉多L = ‘/offline/’, installFilesEssential = [ ‘/’,
‘/manifest.json’, ‘/css/styles.css’, ‘/js/main.js’,
‘/js/offlinepage.js’, ‘/images/logo/logo152.png’ ].concat(offlineURL),
installFilesDesirable = [ ‘/favicon.ico’, ‘/images/logo/logo016.png’,
‘/images/hero/power-pv.jpg’, ‘/images/hero/power-lo.jpg’,
‘/images/hero/power-hi.jpg’ ];

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 配置文件
const
  version = ‘1.0.0’,
  CACHE = version + ‘::PWAsite’,
  offlineURL = ‘/offline/’,
  installFilesEssential = [
    ‘/’,
    ‘/manifest.json’,
    ‘/css/styles.css’,
    ‘/js/main.js’,
    ‘/js/offlinepage.js’,
    ‘/images/logo/logo152.png’
  ].concat(offlineURL),
  installFilesDesirable = [
    ‘/favicon.ico’,
    ‘/images/logo/logo016.png’,
    ‘/images/hero/power-pv.jpg’,
    ‘/images/hero/power-lo.jpg’,
    ‘/images/hero/power-hi.jpg’
  ];

installStaticFiles() 方法应用基于Promise的方法选用Cache
API将文件存款和储蓄到缓存中。

// 安装静态资源 function installStaticFiles() { return
caches.open(CACHE) .then(cache => { // 缓存可选文件
cache.addAll(installFilesDesirable); // 缓存必须文件 return
cache.addAll(installFilesEssential); }); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 安装静态资源
function installStaticFiles() {
  return caches.open(CACHE)
    .then(cache => {
      // 缓存可选文件
      cache.addAll(installFilesDesirable);
      // 缓存必须文件
      return cache.addAll(installFilesEssential);
    });
}

最后,我们抬高中二年级个install的风浪监听器。waitUntil措施有限援救了service
worker不会安装直到其连带的代码被实践。那里它会实施installStaticFiles()方法,然后self.skipWaiting()办法来激活service
worker:

// 应用设置 self.add伊夫ntListener(‘install’, event => {
console.log(‘service worker: install’); // 缓存主要文件 event.waitUntil(
installStaticFiles() .then(() => self.skipWaiting()) ); });

1
2
3
4
5
6
7
8
9
10
11
12
// 应用安装
self.addEventListener(‘install’, event => {
  console.log(‘service worker: install’);
  // 缓存主要文件
  event.waitUntil(
    installStaticFiles()
    .then(() => self.skipWaiting())
  );
});

标题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,你要求在你的页面上注册它。这些手续告诉浏览器你的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已经被登记过,浏览器会自动忽略下边包车型地铁代码。

有3个亟需专门表明的是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是否对你的网站启用了。

皇家赌场手机版 9

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

你会发觉那个效应可以很有益地在叁个效仿窗口中测试你的service
worker,那样你能够关闭和重复打开它,而不会潜移默化到您的新窗口。任何创立在模仿窗口中的注册服务和缓存在窗口被关门时都将没有。

Activate 事件

以此事件会在service
worker被激活时发出。你大概不需求那几个事件,不过在示范代码中,大家在该事件爆发时将老的缓存全部清理掉了:

// clear old caches function clearOldCaches() { return caches.keys()
.then(keylist => { return Promise.all( keylist .filter(key => key
!== CACHE) .map(key => caches.delete(key)) ); }); } // application
activated self.addEventListener(‘activate’, event => {
console.log(‘service worker: activate’); // delete old caches
event.waitUntil( clearOldCaches() .then(() => self.clients.claim())
); });

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
// clear old caches
function clearOldCaches() {
  return caches.keys()
    .then(keylist => {
      return Promise.all(
        keylist
          .filter(key => key !== CACHE)
          .map(key => caches.delete(key))
      );
    });
}
// application activated
self.addEventListener(‘activate’, event => {
  console.log(‘service worker: activate’);
    // delete old caches
  event.waitUntil(
    clearOldCaches()
    .then(() => self.clients.claim())
    );
});

注意self.clients.claim()推行时将会把当下service
worker作为被激活的worker。

Fetch 事件
该事件将会在互联网开始请求时发起。该事件处理函数中,大家能够动用respondWith()方法来威胁HTTP的GET请求然后归来:

  1. 从缓存中取到的财富文件
  2. 尽管第③步失利,财富文件将会从网络中采用Fetch API来获得(和service
    worker中的fetch事件非亲非故)。获取到的财富将会进入到缓存中。
  3. 只要第1步和第①步均未果,将会从缓存中回到正确的能源文件。

// application fetch network data self.addEventListener(‘fetch’, event
=> { // abandon non-GET requests if (event.request.method !== ‘GET’)
return; let url = event.request.url; event.respondWith(
caches.open(CACHE) .then(cache => { return cache.match(event.request)
.then(response => { if (response) { // return cached file
console.log(‘cache fetch: ‘ + url); return response; } // make network
request return fetch(event.request) .then(newreq => {
console.log(‘network fetch: ‘ + url); if (newreq.ok)
cache.put(event.request, newreq.clone()); return newreq; }) // app is
offline .catch(() => offlineAsset(url)); }); }) ); });

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
40
41
// application fetch network data
self.addEventListener(‘fetch’, event => {
  // abandon non-GET requests
  if (event.request.method !== ‘GET’) return;
  let url = event.request.url;
  event.respondWith(
    caches.open(CACHE)
      .then(cache => {
        return cache.match(event.request)
          .then(response => {
            if (response) {
              // return cached file
              console.log(‘cache fetch: ‘ + url);
              return response;
            }
            // make network request
            return fetch(event.request)
              .then(newreq => {
                console.log(‘network fetch: ‘ + url);
                if (newreq.ok) cache.put(event.request, newreq.clone());
                return newreq;
              })
              // app is offline
              .catch(() => offlineAsset(url));
          });
      })
  );
});

offlineAsset(url)情势中应用了部分helper方法来回到正确的多寡:

// 是或不是为图片地址? let iExt = [‘png’, ‘jpg’, ‘jpeg’, ‘gif’, ‘webp’,
‘bmp’].map(f => ‘.’ + f); function isImage(url) { return
iExt.reduce((ret, ext) => ret || url.endsWith(ext), false); } //
return 重临离线财富 function offlineAsset(url) { if (isImage(url)) { //
再次来到图片 return new Response( ‘<svg role=”img” viewBox=”0 0 400 300″
xmlns=”
d=”M0 0h400v300H0z” fill=”#eee” /><text x=”200″ y=”150″
text-anchor=”middle” dominant-baseline=”middle” font-family=”sans-serif”
font-size=”50″ fill=”#ccc”>offline</text></svg>’, {
headers: { ‘Content-Type’: ‘image/svg+xml’, ‘Cache-Control’: ‘no-store’
}} ); } else { // return page return caches.match(offlineURL); } }

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
// 是否为图片地址?
let iExt = [‘png’, ‘jpg’, ‘jpeg’, ‘gif’, ‘webp’, ‘bmp’].map(f => ‘.’ + f);
function isImage(url) {
  
  return iExt.reduce((ret, ext) => ret || url.endsWith(ext), false);
  
}
  
  
// return 返回离线资源
function offlineAsset(url) {
  
  if (isImage(url)) {
  
    // 返回图片
    return new Response(
      ‘<svg role="img" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title>offline</title><path d="M0 0h400v300H0z" fill="#eee" /><text x="200" y="150" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="50" fill="#ccc">offline</text></svg>’,
      { headers: {
        ‘Content-Type’: ‘image/svg+xml’,
        ‘Cache-Control’: ‘no-store’
      }}
    );
  
  }
  else {
  
    // return page
    return caches.match(offlineURL);
  
  }
  
}

offlineAsset()艺术检查请求是不是为三个图片,然后回到1个含有“offline”文字的SVG文件。其余请求将会再次来到offlineU汉兰达L 页面。

Chrome开发者工具中的ServiceWorker部分提供了有关当前页面worker的音信。当中会来得worker中生出的不当,还足以强制刷新,也得以让浏览器进入离线方式。

Cache Storage
部分例举了如今有着曾经缓存的能源。你能够在缓存必要更新的时候点击refresh按钮。

难点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 收藏
评论

皇家赌场手机版 10

Service Worker的装置步骤

在页面上完成注册手续之后,让大家把注意力转到service
worker的脚本里来,在那里面,大家要到位它的安装步骤。

在最大旨的例子中,你必要为install事件定义2个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事件。

第④步:成立可用的离线页面

离线页面能够是静态的HTML,一般用于提示用户眼前呼吁的页面一时不能够选择。不过,大家能够提供部分能够阅读的页面链接。

Cache
API能够在main.js中利用。不过,该API使用Promise,在不协助Promise的浏览器中会失利,全数的JavaScript执行会就此遭受震慑。为了防止那种情景,在做客/js/offlinepage.js的时候我们添加了一段代码来检查当前是否在离线环境中:

/js/offlinepage.js 中以版本号为名称保存了方今的缓存,获取具有U帕杰罗L,删除不是页面包车型客车ULANDL,将那一个U福特ExplorerL排序然后将装有缓存的ULacrosseL映以后页面上:

// cache name const CACHE = ‘::PWAsite’, offlineURL = ‘/offline/’, list
= document.getElementById(‘cachedpagelist’); // fetch all caches
window.caches.keys() .then(cacheList => { // find caches by and order
by most recent cacheList = cacheList .filter(cName =>
cName.includes(CACHE)) .sort((a, b) => a – b); // open first cache
caches.open(cacheList[0]) .then(cache => { // fetch cached pages
cache.keys() .then(reqList => { let frag =
document.createDocumentFragment(); reqList .map(req => req.url)
.filter(req => (req.endsWith(‘/’) || req.endsWith(‘.html’)) &&
!req.endsWith(offlineURL)) .sort() .forEach(req => { let li =
document.createElement(‘li’), a =
li.appendChild(document.createElement(‘a’)); a.setAttribute(‘href’,
req); a.textContent = a.pathname; frag.appendChild(li); }); if (list)
list.appendChild(frag); }); }) });

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
40
41
42
43
44
45
// cache name
const
  CACHE = ‘::PWAsite’,
  offlineURL = ‘/offline/’,
  list = document.getElementById(‘cachedpagelist’);
// fetch all caches
window.caches.keys()
  .then(cacheList => {
    // find caches by and order by most recent
    cacheList = cacheList
      .filter(cName => cName.includes(CACHE))
      .sort((a, b) => a – b);
    // open first cache
    caches.open(cacheList[0])
      .then(cache => {
        // fetch cached pages
        cache.keys()
          .then(reqList => {
            let frag = document.createDocumentFragment();
            reqList
              .map(req => req.url)
              .filter(req => (req.endsWith(‘/’) || req.endsWith(‘.html’)) && !req.endsWith(offlineURL))
              .sort()
              .forEach(req => {
                let
                  li = document.createElement(‘li’),
                  a = li.appendChild(document.createElement(‘a’));
                  a.setAttribute(‘href’, req);
                  a.textContent = a.pathname;
                  frag.appendChild(li);
              });
            if (list) list.appendChild(frag);
          });
      })
  });

如何缓存和再次来到Request

你早就设置了service worker,你未来得以回到您缓存的伸手了。

当service
worker被安装成功还要用户浏览了另一个页面大概刷新了脚下的页面,service
worker将启幕收受到fetch事件。上边是3个事例:

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,大家重临被缓存的值,不然大家回来3个实时从互连网请求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只可以被读取二遍,所以大家得将它克隆出来,一份发给浏览器,一份发给缓存。

开发者工具

Chrome浏览器提供了一连串的工具来提携您来调节ServiceWorker,日志也会直接展现在控制台上。

你最好应用匿超级模特式来展开付出工作,那样可防止去缓存对开发的干扰。

最后,Chrome的Lighthouse壮大也足以为你的渐进式Web应用提供一些改革音讯。

什么立异多个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中进行2个管制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);
          }
        })
      );
    })
  );
});

渐进式Web应用的中央

渐进式Web应用是一种新的技能,所以利用的时候势必要小心。也正是说,渐进式Web应用可以让你的网站在多少个钟头内获取修正,并且在不支持渐进式Web应用的浏览器上也不会潜移默化网站的显得。

而是大家须要考虑以下几点:

处理边界和填坑

这一节内容相比新,有好多待定细节。希望这一节不慢就不要求讲了(因为标准会处理那一个题材——译者注),不过现在,这一个内容依旧应该被提一下。

URL隐藏

当你的运用正是一个单UTucsonL的应用程序时(比如游戏),作者提出您隐藏地址栏。除此之外的状态小编并不提议您隐藏地址栏。在Manifest中,display: minimal-ui 或者 display: browser对此多数气象的话丰盛用了。

万一设置战败了,没有很优雅的措施获得通报

借使二个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中用。

缓存刷新

示范代码中在倡导呼吁以前会先查询缓存。当用户处于离线状态时,那很好,但是要是用户处于在线状态,那他只会浏览到比较老旧的页面。

各类财富比如图片和录制不会改变,所以一般都把这个静态能源设置为深刻缓存。这么些财富得以一贯缓存一年(31,536,000秒)。在HTTP
Header中,正是:

Cache-Control: max-age=31536000

1
Cache-Control: max-age=31536000

页面,CSS诸暨乱弹本文件或然变化的更频繁一些,所以你能够安装3个相比较小的缓存超时时间(24钟头),并保管在用户互连网连接苏醒时再一次从服务器请求:

Cache-Control: must-revalidate, max-age=86400

1
Cache-Control: must-revalidate, max-age=86400

您也得以在历次网站揭露时,通过更名的主意强制浏览重视新请求财富。

fetch()的暗中认可参数

当您使用fetch,缺省级地区级,请求不会带上cookies等凭证,要想带上的话,必要:

JavaScript

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

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

那般设计是有理由的,它比XH瑞鹰的在同源下暗许发送凭据,但跨域时屏弃凭据的规则要来得好。fetch的一言一行更像任何的CO酷路泽S请求,例如<img crossorigin>,它默认不发送cookies,除非你指定了<img crossorigin="use-credentials">.。

小结

从那之后,相信您一旦依据本文一步一步操作下来,你也得以快速把温馨的Web应用转为PWA。在转为了PWA后,借使有选用满足PWA
模型的前端控件的须要,你能够尝试纯前端表格控件SpreadJS,适用于
.NET、Java 和移动端等平台的报表控件一定不会令你失望的。

原稿链接:

1 赞 1 收藏
评论

皇家赌场手机版 11

Non-CO奥迪Q7S私下认可不帮忙

私下认可境况下,从第1方U本田CR-VL跨域得到1个财富将会战败,除非对方扶助了CORubiconS。你能够加上三个non-CO牧马人S选项到Request去幸免失利。代价是这么做会回来1个“不透明”的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步骤缓存3个图形,你有以下二种选取:

  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;" />

皇家赌场手机版 12

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

改变URL Hash的Bug

在M40版本中存在二个bug,它会让页面在改动hash的时候造成service
worker截止工作。

您可以在这里找到越多相关的音讯: 

更加多内容

此处有一些有关的文档能够参见:

得到扶持

若是您遇见麻烦,请在Stackoverflow上发帖询问,使用‘service-worker’标签,以便于大家立时跟进和尽恐怕支持你解决难点。

赞 2 收藏
评论

皇家赌场手机版 13

Leave a Comment.