美文网首页
serviceWorker

serviceWorker

作者: 闲人追风落水 | 来源:发表于2019-07-12 19:33 被阅读0次

Service Worker

使用流程:

1.注册

要安装Service Worker你需要在你的界面上注册它,这个步骤告诉浏览器你的Service Worker脚本放在哪里

if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}).catch(function(err) {
console.log('ServiceWorker registration failed: ', err);
});
}
以上代码会先检测ServiceWorker API在浏览器中是否可用,可用的话一个Service Worker(/sw.js)将被注册,如果这个Service Worker已经注册过了,则浏览器则会忽略以上代码。

注册成功后,则可以打开 chrome://serviceworker-internals/查看浏览器的Service Worker信息。

特别注意的是Service Worker文件的路径问题,你一定注意到了,上面代码中sw.js存放在网站的根路径下,如果存放在网站的根路径下,则表示该Service Worker将会收到该网站的所有fetch事件,如果我们将Service Worker文件注册为/example/sw.js,则代表该Service Worker将只会收到/example/路径下的fetch事件。

以上步骤只是注册了一个Service Worker脚本,注册完成后将会安装,安装过程在Service Worker脚本中进行

2.sw.js

var CACHE_NAME = "my_cache";
var urlsToCache = [
'/index.html',
'/css/style.css',
'/js/script.js'
];
//这里的self代表ServiceWorkerGlobalScope 全局作用域
self.addEventListener('install', function(event) {
//这里的waitUtil会在安装成功之前执行一些预装的操作,但是只建议做一些轻量级和非常重要资源的缓存,减少安装失败的概率。安装成功
//后ServiceWorker状态会从installing变为installed
event.waitUntil(
caches.open(CACHE_NAME).then(function(cache) {
console.log('Opendhe : ',cache);
return cache.addAll(urlsToCache);
})
);
});
CACHE_NAME代表这个缓存的名字,urlToCache代表初次缓存的文件

上面的代码中,我们通过caches.open(关于caches的介绍请看 )打开我们指定的cache文件名,然后我们调用cache.addAll并传入我们的文件数组。这是通过一连串的promise(caches.open和caches.addAll)完成的event.waitUntil拿到一个promise的状态来获取安装是否成功,如果所有的文件都被缓存成功了,那么Service Worker就安装成功了。如果任何一个文件下载安装失败,那么整个Service Worker的安装就失败。这意味着你需要非常谨慎地决定那些文件需要在安装步骤中被缓存,指定太多文件的话就会增加整个Service Worker应用安装失败的概率。

2.利用Service Worker监听网络请求(伪造相应或增加缓存文件)

3.销毁

是否销毁由浏览器决定,如果一个Service Worker长期不使用或者机器内存有限,则浏览器可能会销毁这个Service Worker

4.利用Service Worker监听网络请求

当Service Worker被安装成功并且用户浏览了另一个页面,Service Worker将开始接受fetch事件。下面是一个例子:

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,我们返回被缓存的值,否则我们返回一个实时从网络请求的结果。

如果我们想要增量的缓存新的请求,我们可以通过处理fetch请求的response并且添加它们到缓存中来实现,例如:

self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
if (response) {
return response;
}
var fetchRequest = event.request.clone();
return fetch(fetchRequest).then(
function(response) {
if(!response || response.status !== 200 ||!response.headers.get('Content-type').match(/image/)) {
return response;
}
var responseToCache = response.clone();
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});

        return response;  
      }  
    );  
  })  
);

首先检查缓存中是否已经缓存了这个请求,如果有,则直接返回相应,这样就减少了一次网络请求,否则有Service Worker发起请求,这时的Service Worker起到一个中间代理的作用。

Service Worker请求的过程通过fetch api完成,得到response对象之后进行过滤,查看是否是图片文件,如果不是,则直接返回请求,不会缓存。 如果是图片文件,要先复制一份response,原因是request或者response对象属于stream,只能使用一次,之后一份存入缓存,另一份发送个页面。

这就是Service Worker的强大之处:拦截请求,伪造请求。在这个过程中fetch API起到了很大的作用。

5.与Service Worker相关的事件

fetch事件:

在页面发起http/https请求时,Service Worker可以通过fetch事件拦截请求,并且给出自己的相应。w3c提供了一个新的fetch API可用于取代XMLHttpRequest,与XMLHttpRequest最大的不同就是:fetch方法返回的是promise对象,可通过then方法进行连续调用,减少嵌套。

message事件:

页面和ServiceWorker质检可以通过postMessage方法发送消息,发送的消息可以通过message事件接收到。这是一个双向的过程,页面可以发消息给Service Worker,Service Worker也可以发送消息给页面,由于这个特性,可以将Service Worker作为中间纽带,使得一个域名或者子域名下的多个页面自由通信页可以实现服务器消息推送的功能。

例子代码app.js

if('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js').then(function(registration) {
if(registration.installing) {
console.log('Service worker installing');
} else if(registration.waiting) {
console.log('Service worker installed');
} else if(registration.active) {
console.log('Service worker active');
}
console.log('ServiceWorker注册成功作用域为:', registration.scope);
}).catch(function(err) {
console.log('ServiceWorker注册失败原因是:', err);
});
}
例子sw.js代码

var CACHE_NAME ='mfacai002';
this.addEventListener('install', function(event) {
self.skipWaiting()//删除旧的service
event.waitUntil(caches.open(CACHE_NAME).then(function(cache) {
cache.addAll([

    ]);
}));

});

//删除就的service
self.addEventListener('activate', function(event) {
var cacheWhitelist = ['mfacai002'];
event.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (cacheWhitelist.indexOf(key) === -1) {
return caches.delete(key);
}
}));
})
);
});

self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request)
.then(function(response){
// Cache hit - return response
if (response) {
return response;
}
// 克隆请求。因为请求是一个“stream”,只能用一次。但我们需要用两次,一次用来缓存,一次给浏览器抓取内容,所以需要克隆
var fetchRequest = event.request.clone();
// 返回请求的内容
return fetch(fetchRequest).then(
function(response){
// 检查是否为有效的响应。basic表示同源响应,也就是说,这意味着,对第三方资产的请求不会添加到缓存。
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// 同request,response是一个“stream”,只能用一次,但我们需要用两次,一次用来缓存一个返回给浏览器,所以需要克隆。
var responseToCache = response.clone();
// 缓存新请求
caches.open(CACHE_NAME)
.then(function(cache){
cache.put(event.request, responseToCache)
});
return response;
}
);
})
);
});

相关文章

  • serviceWorker

    Service Worker 使用流程: 1.注册 要安装Service Worker你需要在你的界面上注册它,这...

  • ServiceWorker

    概念 Service Worker 是HTML5 的一个新特性,主要用来做持久的离线缓存。 应用场景 在公司业务中...

  • serviceWorker

    参考一参考二

  • PWA

    if ('serviceWorker' in navigator) {navigator.serviceWorke...

  • js的cache对象

    PWA的兴起带动了对ServiceWorker的关注,而说到ServiceWorker又不得不谈一下cache,我...

  • create-react-app脚手架使用记录

    Failed to register a ServiceWorker: The URL protocol of t...

  • serviceWorker 入门

    前提 本文涉及几个知识点:fetch、caches、indexDB 等都不会详细介绍,仅对于其中某些点带过 一. ...

  • PWA系列 - Web Workers 线程模型

    前言 本文是Chromium官方设计文档Blink Workers主旨内容的翻译,介绍ServiceWorker在...

  • 使用workbox在webpack里配置serviceworke

    1、本项目是在react的webpack项目里使用workbox来配置serviceworker 2、仅支持htt...

  • [周分享] 浏览器 缓存机制

    拓展: 设计一个无懈可击的浏览器缓存方案:关于思路,细节,ServiceWorker,以及 HTTP/2https...

网友评论

      本文标题:serviceWorker

      本文链接:https://www.haomeiwen.com/subject/feoykctx.html