原生App拥有Web应用通常所不具备的富离线体验,

fetch()近些日子仅补助Service Workers

fetch马上帮忙在页面上利用了,但是近来的Chrome达成,它还只帮助service worker。cache API也即将要页面上被帮助,可是近年来停止,cache也还不得不在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 收藏 评论

必威 1

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

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

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

我们是何许选取 service worker 来为 theguardian.com 创设一个自定义的离线页面。

必威 2

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

你正在朝着集团途中的大巴里,在小弟大上开辟了 Guardian 应用。的士被隧道包围着,然而这几个应用可以健康运转,尽管没有网络连接,你也能获得完整的功效,除了出示的从头到尾的经过恐怕有一点点旧。假设你品尝在网址上也那样干,缺憾它完全没办法加载:

必威 3

安卓版 Chrome 的离线页面

Chrome 中的这么些彩蛋,很三人都不掌握》

Chrome 在离线页面上有个藏匿的游艺(桌面版上按空格键,手提式有线电电话机版上点击那只恐龙),这有些能缓慢解决一点您的一点也不快。但是大家能够做得越来越好。

Service workers 允许网址小编拦截本人站点的装有互联网央浼,那也就代表大家得以提供完善的离线体验,就好像原生应用同样。在 Guardian 网址,大家近期上线了二个自定义的离线体验效果。当客商离线的时候,他们会看到二个富含Guardian 标识的页面,上面带有二个粗略的离线提醒,还也许有二个填字游戏,他们能够在守候网络连接的时候玩玩那个找点乐子。那篇博客解释了大家是何等塑造它的,可是在起来此前,你可以先本身探寻看。

4. Http/Manifest/Service Worker三种cache的关系

要缓存能够应用三种手腕,使用Http Cache设置缓存时间,也足以用Manifest的Application Cache,还足以用ServiceWorker缓存,假若三者都用上了会什么呢?

会以Service Worker为优先,因为ServiceWorker把必要拦截了,它首先做拍卖,假设它缓存库里部分话一向回到,未有的话平常乞求,就约等于尚未ServiceWorker了,那年就到了Manifest层,Manifest缓存里要是局地话就取那个缓存,如果未有的话就相当于尚未Manifest了,于是就能够从Http缓存里取了,假如Http缓存里也一贯不就能够发需要去获取,服务端依照Http的etag只怕Modified 提姆e恐怕会再次回到304 Not Modified,不然符合规律重回200和数量内容。那正是整三个到手的进程。

就此只要既用了Manifest又用ServiceWorker的话应该会导致同多个财富存了四次。不过足以让帮忙ServiceWorker的浏览器选取Service Worker,而不援助的选拔Manifest.

开展阅读

除此以外,还大概有多少个很棒的离线作用案例。如:Guardian 营造了多个颇具 crossword puzzle(填字游戏)的离线 web 页面 – 因而,即便等待网络重连时(即已在离线状态下),也能找到一点乐趣。小编也引入看看 Google Chrome Github repo,它含有了成都百货上千不一的 Service Worker 案例 – 个中有的采取案例也在那!

而是,倘诺您想跳过上述代码,只是想大约地由此二个库来管理有关操作,那么自身推荐你看看 UpUp。那是二个轻量的台本,能令你更轻巧地利用离线功效。

打赏帮助我翻译越多好小说,感谢!

打赏译者

管理边界和填坑

这一节内容相比新,有好多待定细节。希望这一节极快就无需讲了(因为规范会管理那些主题材料——译者注),但是未来,那一个剧情还是应当被提一下。

生命周期

先来看一下一个service worker的运作周期

必威 4
上海体育场面是service worker生命周期,出处

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

  1.  安装

2.  激活,激活成功今后,展开chrome://inspect/#service-workers能够查看到日前运作的service worker

必威 5

  1. 监听fetch和message事件,下边三种事件会举办轻巧描述

  2. 销毁,是不是销毁由浏览器决定,假如四个service worker长时间不使用如故机器内部存款和储蓄器有数,则可能会销毁那么些worker

试试看

你需求八个帮助 Service Worker 和 fetch API 的浏览器。截至到本文编写时只有Chrome(手机版和桌面版)同期扶助这三种 API(译者注:Opera 这段日子也支撑这两个),但是 Firefox 相当慢将在帮衬了(在每一天更新的版本中早已支撑了),除外 Safari 之外的享有浏览器也都在探寻。别的,service worker 只可以登记在选拔了 HTTPS 的网址上,theguardian.com 已经上马稳步搬迁到 HTTPS,所以我们只辛亏网址的 HTTPS 部分提供离线体验。就当前来说,我们接纳了 开拓者博客 作为大家用来测验的地点。所以只要您是在我们网址的 开辟者博客 部分阅读那篇小说的话,很幸运。

当你选取帮衬的浏览器访谈大家的 开垦者博客 中的页面包车型客车时候,一切就打算妥帖了。断开你的网络连接,然后刷新一下页面。假令你和谐没标准尝试的话,能够看一下这段 演示录制(译者注:需梯子)。

3. 使用Service Worker

ServiceWorker的选择套路是先挂号一个Worker,然后后台就能够运行一条线程,能够在那条线程运转的时候去加载一些财富缓存起来,然后监听fetch事件,在那么些事件里拦截页面包车型大巴伸手,先看下缓存里有没有,假设有直接回到,否则平常加载。可能是一开头不缓存,每种财富央求后再拷贝一份缓存起来,然后下一回呼吁的时候缓存里就有了。

接纳 Service worker 创设四个特别轻巧的离线页面

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

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

让大家想像以下情状:我们那时候在一辆通往农村的列车的里面,用运动道具看着一篇很棒的篇章。与此同一时候,当你点击“查看更加的多”的链接时,高铁突然步入了隧道,导致移动设备失去了互联网,而 web 页面会呈现出类似以下的剧情:

必威 6

那是一定让人寒心的体验!幸运的是,web 开采者们能通过有个别新特征来改革那类的顾客体验。笔者近日径直在折腾 ServiceWorkers,它给 web 带来的点不清恐怕性总能给自个儿欣喜。Service Workers 的奇妙特质之一是允许你检测互联网乞求的情状,并让您作出相应的响应。

在那篇小说里,小编策画用此天性检查顾客的当前网络连接情况,就算没连接则赶回一个极品轻易的离线页面。固然那是五个至极基础的案例,但它能给您带来启迪,让您精晓运转并运维该性格是多么的简练!假若您没理解过 瑟维斯 Worker,小编建议你看看此 Github repo,精通越来越多相关的新闻。

在此案例早先前,让大家先轻便地走访它的劳作流程:

  1. 在客商第二回访谈大家的页面时,我们会设置 ServiceWorker,并向浏览器的缓存加多我们的离线 HTML 页面
  2. 下一场,假设顾客绸缪导航到另三个 web 页面(同三个网址下),但此刻已断网,那么我们将再次来到已被缓存的离线 HTML 页面
  3. 只是,若是顾客策画导航到别的四个 web 页面,而那时候互连网已接连,则能照常浏览页面

改变URL Hash的Bug

在M40版本中设有四个bug,它会让页面在改变hash的时候产生service worker结束专门的职业。

您能够在那边找到更加多相关的新闻: 

使用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是多少个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的进程中,也蒙受了有的难题,上面是中间多个

打赏支持自身翻译越来越多好小说,多谢!

必威 7

1 赞 收藏 评论

(3)fetch资源后cache起来

正如代码,监听fetch事件做些管理:

JavaScript

this.addEventListener("fetch", function(event) { event.respondWith( caches.match(event.request).then(response => { // cache hit if (response) { return response; } return util.fetchPut(event.request.clone()); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
this.addEventListener("fetch", function(event) {
    event.respondWith(
        caches.match(event.request).then(response => {
            // cache hit
            if (response) {
                return response;
            }
            return util.fetchPut(event.request.clone());
        })
    );
});

先调caches.match看一下缓存里面是或不是有了,假如有一直回到缓存里的response,不然的话符合规律诉求财富并把它放到cache里面。放在缓存里能源的key值是Request对象,在match的时候,必要要求的url和header都同样才是千篇一律的能源,能够设定第3个参数ignoreVary:

JavaScript

caches.match(event.request, {ignoreVary: true})

1
caches.match(event.request, {ignoreVary: true})

代表一旦央求url一样就认为是同一个能源。

上边代码的util.fetchPut是这么完成的:

JavaScript

let util = { fetchPut: function (request, callback) { return fetch(request).then(response => { // 跨域的财富直接return if (!response || response.status !== 200 || response.type !== "basic") { return response; } util.putCache(request, response.clone()); typeof callback === "function" && callback(); return response; }); }, putCache: function (request, resource) { // 后台不要缓存,preview链接也毫不缓存 if (request.method === "GET" && request.url.indexOf("wp-admin") < 0 && request.url.indexOf("preview_id") < 0) { caches.open(CACHE_NAME).then(cache => { cache.put(request, resource); }); } } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let util = {
    fetchPut: function (request, callback) {
        return fetch(request).then(response => {
            // 跨域的资源直接return
            if (!response || response.status !== 200 || response.type !== "basic") {
                return response;
            }
            util.putCache(request, response.clone());
            typeof callback === "function" && callback();
            return response;
        });
    },
    putCache: function (request, resource) {
        // 后台不要缓存,preview链接也不要缓存
        if (request.method === "GET" && request.url.indexOf("wp-admin") < 0
              && request.url.indexOf("preview_id") < 0) {
            caches.open(CACHE_NAME).then(cache => {
                cache.put(request, resource);
            });
        }
    }
};

亟待专心的是跨域的能源无法缓存,response.status会重临0,若是跨域的财富支撑COOdysseyS,那么能够把request的mod改成cors。假使央求退步了,如404或许是逾期等等的,那么也向来回到response让主页面管理,不然的话表明加载成功,把那么些response克隆一个内置cache里面,然后再回去response给主页面线程。注意能减缓存里的能源一般只好是GET,通过POST获取的是不能够缓存的,所以要做个判别(当然你也得以手动把request对象的method改成get),还应该有把一部分私家不希望缓存的能源也做个推断。

那般只要客户张开过一回页面,ServiceWorker就设置好了,他刷新页面或许张开第一个页面包车型地铁时候就能够把须求的财富一一做缓存,满含图片、CSS、JS等,只要缓存里有了不管顾客在线或许离线都能够健康访谈。这样大家当然会有多少个主题素材,这几个缓存空间到底有多大?上一篇大家关系Manifest也毕竟地点存款和储蓄,PC端的Chrome是5Mb,其实这些说法在新本子的Chrome已经不准确了,在Chrome 61版本能够见到地面存储的空仲春使用情况:

必威 8

当中Cache Storage是指ServiceWorker和Manifest占用的上空尺寸和,上海体育场面能够看出总的空间大小是20GB,差相当的少是unlimited,所以基本上不用忧郁缓存会缺乏用。

打赏扶助自身翻译愈来愈多好小说,多谢!

任选一种支付办法

必威 9 必威 10

1 赞 3 收藏 1 评论

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

必威 11

主题材料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,在调解进度中日常等上一两秒钟才会利用新的,比较抓狂。

干活规律

经过一段轻松的 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,你会看到特意为你订制的本性化内容,它们是在您前面访问网址时由浏览器缓存下来的。它在设置进程中也不会生出任何困难,你所需求的只是访谈那个网站而已,不像原生应用,还亟需顾客有多个运用商号的账号工夫设置。瑟维斯worker 一样能够支持大家升高网址的加载速度,因为网址的框架能够被有限协助地缓存下来,就好像原生应用同样。

一旦你对 service worker 很感兴趣,想要领悟更加多内容的话,开荒者 马特Gaunt(Chrome的肝胆相照支持者)写了一篇特别详实地 介绍 Service Worker的文章。

打赏辅助自身翻译愈来愈多好文章,感谢!

打赏译者

5. 采纳Web App Manifest加多桌面入口

专心这里说的是其它贰个Manifest,那么些Manifest是三个json文件,用来放网址icon名称等音讯以便在桌面增多四个Logo,以及创建一种张开这一个网页如同张开App同样的效应。上边一向说的Manifest是被丢弃的Application Cache的Manifest。

本条Maifest.json文件能够那样写:

JavaScript

{ "short_name": "人人FED", "name": "人人网FED,专一于前面贰个技艺", "icons": [ { "src": "/html/app-manifest/logo_48.png", "type": "image/png", "sizes": "48x48" }, { "src": "/html/app-manifest/logo_96.png", "type": "image/png", "sizes": "96x96" }, { "src": "/html/app-manifest/logo_192.png", "type": "image/png", "sizes": "192x192" }, { "src": "/html/app-manifest/logo_512.png", "type": "image/png", "sizes": "512x512" } ], "start_url": "/?launcher=true", "display": "standalone", "background_color": "#287fc5", "theme_color": "#fff" }

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
{
  "short_name": "人人FED",
  "name": "人人网FED,专注于前端技术",
  "icons": [
    {
      "src": "/html/app-manifest/logo_48.png",
      "type": "image/png",
      "sizes": "48x48"
    },
    {
      "src": "/html/app-manifest/logo_96.png",
      "type": "image/png",
      "sizes": "96x96"
    },
    {
      "src": "/html/app-manifest/logo_192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "/html/app-manifest/logo_512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": "/?launcher=true",
  "display": "standalone",
  "background_color": "#287fc5",
  "theme_color": "#fff"
}

icon必要预备种种尺码,最大必要512px * 512px的,那样Chrome会自动去挑选合适的图形。借使把display改成standalone,从转变的Logo展开就能够像展开三个App同样,未有浏览器地址栏这个东西了。start_url内定张开今后的输入链接。

然后加多三个link标签指向那一个manifest文件:

JavaScript

<link rel="manifest" href="/html/app-manifest/manifest.json">

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

与上述同类组合Service Worker缓存:
必威 12把start_url指向的页面用ServiceWorker缓存起来,那样当顾客用Chrome浏览器张开这么些网页的时候,Chrome就能够在底层弹一个提示,询问顾客是还是不是把那几个网页加多到桌面,假如点“增多”就能够变动二个桌面Logo,从那个图标点进去就好像展开贰个App同样。感受如下:

必威 13

正如为难的是Manifest近日唯有Chrome帮衬,何况只好在安卓系统上运用,IOS的浏览器无法增添三个桌面Logo,因为IOS未有开放这种API,可是作者的Safari却又是足以的。

综上,本文介绍了怎么用Service Worker结合Manifest做三个PWA离线Web 应用软件,首倘使用ServiceWorker调整缓存,由于是写JS,比较灵敏,还足以与页面举行通信,此外通过必要页面包车型客车换代时间来判断是不是必要更新html缓存。ServiceWorker的兼容性不是专门好,但是前景比较光明,浏览器都在准备协理。现阶段得以结合offline cache的Manifest做离线应用。

连锁阅读:

  1. 干什么要把网站进级到HTTPS
  2. 怎么样把网址晋级到http/2
  3. 本人是怎么样让网址用上HTML5 Manifest

1 赞 1 收藏 评论

必威 14

让我们先河吧

要是你有以下 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.add伊芙ntListener('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 访问互连网)

必威 15

借使你刷新页面,你应当能收六柱预测应的离线页面!

必威 16

借让你只想大概地质衡量试该意义而不想写任何代码,那么你能够访问小编已开立好的 demo。其他,上述全体代码能够在 Github repo 找到。

自家驾驭用在此案例中的页面非常粗大略,但你的离线页面则取决于你自个儿!如若你想深远该案例的剧情,你可以为离线页面增多缓存破坏( cache busting),如: 此案例。

本文由必威发布于必威-前端,转载请注明出处:原生App拥有Web应用通常所不具备的富离线体验,

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