资讯专栏INFORMATION COLUMN

Service Worker 基本用法

Charlie_Jade / 2852人阅读

摘要:在服务工作线程中,延长事件的寿命从而阻止浏览器在事件中的异步操作完成之前终止服务工作线程。在事件中,它延迟将视为已激活的,直到传递的被成功地。这主要用于确保任何功能事件不会被分派到对象,直到它升级数据库模式并删除过期的缓存条目。

看了很多介绍Service Worker的,看得都挺模糊的,所以决定自己写一篇文件整理一下思路。

一、Service Worker API 名词区分

1、ServiceWorkerContainer:navigator.serviceWorker返回的就是Service WorkerContainer对象,主要是用户在页面注册serviceWorker,调用方法:

navigator.serviceWorker.register(scriptURL, options)
    .then(function(ServiceWorkerRegistration) { ... })

2、ServiceWokrerGlobalScope:主要是用户在sw.js文件的全局变量,即this的指向
3、ServiceWorkerRegistration:在页面调用serviceWorker.register注册返回一个Promise对象,当resolve时传递给then的函数参数就是ServiceWorkerRegistration.
4、ServiceWorker:表示ServiceWorkerRegistration.installing || ServiceWorkerRegistration.waiting || ServiceWorkerRegistration.active

二、Service Worker 注册

1、index.html

2、sw.js

var CACHE_NAME = "sw-test-v1";
this.addEventListener("install",function(event){
    console.log("installing...");
    event.waitUntil(caches.open(CACHE_NAME).then(function(cache){
        cache.addAll([
            "images/resource01.jpg",
            "images/resource02.jpg",
            ....
        ]);
    }));
});
this.addEventListener("fetch", function(event) {
    event.respondWith(
        caches.match(event.request)
            .then(function(response) {
                if (response) { // 缓存命中,返回缓存
                    return response;
                }
                // 请求是stream数据,只能使用一次,所以需要拷贝,一次用于缓存,一次用于浏览器请求
                var fetchRequest = event.request.clone();
                return fetch(fetchRequest)
                    .then(function(response) {
                        if(!response || response.status !== 200) {
                            return response;
                        }
                        // 响应也是stream,只能使用一次,一次用于缓存,一次用于浏览器响应
                        var responseToCache = response.clone();
                        caches.open(CACHE_NAME)
                            .then(function(cache) {
                                cache.put(event.request, responseToCache);
                            });
                        return response;
                    });
            })
  );
});

sw.js工作内容:首先监听install事件,调用cache.addAll()方法将静态资源加入缓存中。然后监听fetch事件,判断当前请求的url是否在缓存中,如果在则返回内容,如果不在,则向服务端发起请求数据,将返回的数据放入缓存中并且返回给浏览器。
代码中的方法解析:
1、caches.match():检查给定的Request对象或url字符串是否是一个已存储的 Response对象的key. 该方法针对 Response 返回一个 Promise ,如果没有匹配则返回 undefined 。cache对象按创建顺序查询,等同于在每个缓存上调用 cache.match() 方法 (按照caches.keys()返回的顺序) 直到返回Response 对象。语法如下:

caches.match(request, options).then(function(response) {
  // Do something with the response
});

参数解析:

options: 可选,配置对象中的属性控制在匹配操作中如何进行匹配选择,具体属性如下:

ignoreSearch: Boolean值, 指定匹配过程是否应该忽略url中查询参数,默认 false。

ignoreMethod: Boolean 值,当被设置为 true 时,将会阻止在匹配操作中对 Request请求的 http 方式的验证 (通常只允许 GET 和 HEAD 两种请求方式)。该参数默认为 false.

ignoreVary: Boolean 值,当该字段被设置为 true, 告知在匹配操作中忽略对VARY头信息的匹配。换句话说,当请求 URL 匹配上,你将获取匹配的 Response 对象,无论请求的 VARY 头存在或者没有。该参数默认为 false.

cacheName: DOMString 值, 表示所要搜索的缓存名称。

2、caches.open():返回一个resolve为匹配 cacheName 的 cache 对象的 Promise .如果指定的 cache 不存在,则使用该 cacheName 创建一个新的cache并返回。

caches.open(cacheName).then(function(cache) {});

3、cache.addAll():将静态资源加入缓存中

cache.addAll(requests[]).then(function() {
  // 已加入缓存
});

该方法会覆盖掉以前存储在缓存中的匹配的健值对,但是后面监听对fetch事件中调用cache.put()方法又会覆盖掉之前在cache.addAll()中添加到缓存中所匹配的健值对。
4、cache.put():允许将键/值对添加到当前的 Cache 对象中.它将覆盖先前存储在匹配请求的cache中的任何键/值对。
注意: Cache.add/Cache.addAll 不会缓存 Response.status 值不在200范围内的响应,而 Cache.put 允许你存储任何请求/响应对。因此,Cache.add/Cache.addAll 不能用于不透明的响应,而 Cache.put 可以。

cache.put(request, response).then(function() {
  // request/response pair has been added to the cache
});

5、event.waitUntil():扩展了事件的生命周期。在服务工作线程中,延长事件的寿命从而阻止浏览器在事件中的异步操作完成之前终止服务工作线程。
install事件中,它延迟将被安装的worker视为 installing ,直到传递的 Promise 被成功地resolve。主要用于确保:服务工作线程在所有依赖的核心cache被缓存之前都不会被安装。
activate事件中,它延迟将 active worker视为已激活的,直到传递的 Promise 被成功地resolve。这主要用于确保:任何功能事件不会被分派到 ServiceWorkerGlobalScope 对象,直到它升级数据库模式并删除过期的缓存条目。
当该方法运行时,如果 Promise 是resolved,任何事情都不会发生;如果 Promise 是rejected,installing 或者 active worker的 state 会被设置为redundant。
语法:event.waitUntil(promise)
6、event.respondWith():阻止浏览器默认的fetch处理方法,允许用户自己提供一个promise对象作为response返回。

fetchEvent.respondWith(
  // Promise that resolves to a Response.
​)

Parameters:A Promise for a Response.

上面的sw.js只是一个最基本的serviceWorker,在日常工作中,我们还需要考虑更新。

三、Service Worker更新 (一)自动更新
this.addEventListener("install",function(event){
    this.skipWaiting();
});
this.addEventListener("activate", function (event) {
    this.clients.claim();
});

skipWaiting(): 强制等待中的service worker跳过等待成为激活的service worker。虽然该方法在任何时候都是可以调用的,但是只有在新安装的service worker仍然处于等待状态时才会起作用;所以在install事件里面调用是非常常见的。与clients.claim()一起调用以确保更新当前的client和其他激活的clients。
clients.claim(): 允许一个激活的service worker将其设置为其他同scope下的clients的controller。该方法会触发要被该service worker控制的其他任何clients的navigator.serviceWorker上的"controllerchange"事件。
当一个service worker初始注册时并不会使用该service worker,直到下次加载页面时。该方法会让这些页面直接被控制,注意,这将导致你的service worker将控制定期加载的页面,也有可能控制其他service worker加载的页面。

(二)手动更新

手动更新主要是调用在index.html注册serviceWorker时的registration的update()方法:ServiceWorkerRegistration.update();
它会获取worker的脚本URL,如果新的worker与当前的worker并不是完全相同的(byte-by-byte identical)则安装新的worker;如果前一次worker获取发生在24小时之前,则worker的获取将绕过任何浏览器缓存。

navigator.serviceWorker.register("./sw.js").then(function(registration){
   registration.update();
});

参考学习链接:
https://developer.mozilla.org...
https://developers.google.cn/...
https://lavas.baidu.com/pwa/o...
https://segmentfault.com/a/11...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/62098.html

相关文章

  • service-worker用法详解

    摘要:二简要介绍是一段脚本,在后台运行。作为一个独立的线程,不会对页面造成阻塞。本质上充当应用程序与浏览器之间的代理服务器。可以做到离线使用消息推送后台自动更新,的出现是正是为了使得也可以具有类似的能力。在我们的例子例,是在,的根目录是。 一、背景 taro框架转的h5,想在无网络状态下可以控制展示给用户的界面,使用客户端离线缓存可以达到目的,并且可以将静态资源进行缓存,从而减少白屏时间,加...

    104828720 评论0 收藏0
  • 精读《Caches API》

    摘要:引言这个是针对的。一般结合使用,因为请求级别的缓存与具有页面拦截功能的最配。本周精读的文章是,介绍了浏览器缓存接口的基本语法。包含任意命名空间,可以通过创建或访问。精读笔者利用实现了纯浏览器端的后端渲染。前端精读帮你筛选靠谱的内容。 1 引言 caches 这个 API 是针对 Request Response 的。caches 一般结合 Service Worker 使用,因为请求级...

    Null 评论0 收藏0
  • Service Worker学习与实践(一)——离线缓存

    摘要:的本质是一个,它独立于主线程,因此它不能直接访问,也不能直接访问对象,但是,可以访问对象,也可以通过消息传递的方式与主线程进行通信。的最佳用法其实就是配合做离线缓存。 什么是Service Worker Service Worker本质上充当Web应用程序与浏览器之间的代理服务器,也可以在网络可用时作为浏览器和网络间的代理。它们旨在(除其他之外)使得能够创建有效的离线体验,拦截网络请...

    xiaochao 评论0 收藏0
  • pwa-之service worker 基本概念

    摘要:是浏览器和服务器之间的脚本,主要作用是拦截请求,修改响应,以及一些其他的作用。这是出于安全因素的考虑。这个注册的过程是发生在之外的。在安装完成,激活之前,它不会拦截任何请求。将会始终拦截请求,重启页面也是为了这个。 pwa-之service worker 基本概念pwa-之service worker 离线文件处理 学习service worker 基本概念 在本章,将涵盖以下内容 ...

    galaxy_robot 评论0 收藏0
  • pwa-之service worker 基本概念

    摘要:是浏览器和服务器之间的脚本,主要作用是拦截请求,修改响应,以及一些其他的作用。这是出于安全因素的考虑。这个注册的过程是发生在之外的。在安装完成,激活之前,它不会拦截任何请求。将会始终拦截请求,重启页面也是为了这个。 pwa-之service worker 基本概念pwa-之service worker 离线文件处理 学习service worker 基本概念 在本章,将涵盖以下内容 ...

    olle 评论0 收藏0

发表评论

0条评论

Charlie_Jade

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<