Service Worker简介

Service Worker是什么

Service Worker是一个注册在指定源和路径下的事件驱动 worker。它采用JavaScript控制关联的页面或者网站,拦截并修改访问和资源请求,细粒度地缓存资源。你可以完全控制应用在特定情形(最常见的情形是离线)下的表现。

Service Worker作用

Service Worker 中我们可以做很多事情,比如拦截客户端的请求、向客户端发送消息、向服务器发起请求等等,其中最重要的作用之一就是离线资源缓存 ([淘宝]、[网易新闻])

Service Worker特征
  • Service Worker 工作在 worker context 中,是没有访问 DOM 的权限的,所以我们无法在 Service Worker 中获取 DOM 节点,也无法在其中操作 DOM 元素;
  • 我们可以通过 postMessage 接口把数据传递给其他 JS 文件;
  • Service Worker 中运行的代码不会被阻塞,也不会阻塞其他页面的 JS 文件中的代码

Service Worker运行在worker上下文,因此它不能访问DOM。相对于驱动应用的主JavaScript线程,它运行在其他线程中,所以不会造成阻塞。它设计为完全异步,同步API(如XHRlocalStorage)不能在service worker中使用。
出于安全考量,Service workers只能由HTTPS承载,毕竟修改网络请求的能力暴露给中间人攻击会非常危险。

使用Service Worker

上面说到 Service Worker必须使用https协议,但本地开发弄个https协议是很麻烦的。好在还算人性化,Service Worker在http://localhost或者http://127.0.0.1这种本地环境下的时候是可以跑起来的。

注册安装

下面就让我们来使用 Service Worker 。

如果当前使用的浏览器支持 Service Worker ,则在 window.navigator 下会存在 serviceWorker 对象,我们可以使用这个对象的 register 方法来注册一个 Service Worker。

这里需要注意的一点是,Service Worker 在使用的过程中存在大量的 Promise ,对于 Promise 不是很了解的同学可以先去看一下相关文档。 Service Worker 的注册方法返回的也是一个 Promise 。

// index.js
if ('serviceWorker' in window.navigator) {
  navigator.serviceWorker.register('./sw.js', { scope: './' })
    .then(function (reg) {
      console.log('success', reg);
    })
    .catch(function (err) {
      console.log('fail', err);
    });
}
复制代码

在这段代码中,我们先使用 if 判断下浏览器是否支持 Service Worker ,避免由于浏览器不兼容导致的 bug 。
register 方法接受两个参数,第一个是 service worker 文件的路径,请注意:这个文件路径是相对于 Origin ,而不是当前 JS 文件的目录的;第二个参数是 Serivce Worker 的配置项,可选填,其中比较重要的是 scope 属性。按照文档上描述,它是 Service Worker 控制的内容的子目录,这个属性所表示的路径不能在 service worker 文件的路径之上,默认是 Serivce Worker 文件所在的目录;

register 方法返回一个 Promise 。如果注册失败,可以通过 catch 来捕获错误信息;如果注册成功,可以使用 then 来获取一个 ServiceWorkerRegistration 的实例,有兴趣的同学可以去翻阅文档。
注册完 Service Worker 之后,浏览器会为我们自动安装它,因此我们就可以在 service worker 文件中监听它的 install 事件了。

// sw.js
this.addEventListener('install', function (event) {
  console.log('Service Worker install');
});
复制代码

同样的,Service Worker 在安装完成后会被激活,所以我们也可监听 activate 事件。

// sw.js
this.addEventListener('activate', function (event) {
  console.log('Service Worker activate');
});
复制代码

这时,我们可以在 Chorme 的开发者工具中看到我们注册的 Service Worker。

在这里插入图片描述
在默认情况下,Service Worker 必定会每24小时被下载一次,如果下载的文件是最新文件,那么它就会被重新注册和安装,但不会被激活,当不再有页面使用旧的 Service Worker 的时候,它就会被激活。

在这里插入图片描述

这对于我们开发来说是很不方便的,因此在这里我勾选了一个名为 Update on reload 的单选框,选中它之后,我们每次刷新页面都能够使用最新的 service worker 文件。
在同一个 Origin 下,我们可以注册多个 Service Worker。但是请注意,这些 Service Worker 所使用的 scope 必须是不相同的

if ('serviceWorker' in window.navigator) {
  navigator.serviceWorker.register('./sw/sw.js', { scope: './sw' })
    .then(function (reg) {
      console.log('success', reg);
    })
  navigator.serviceWorker.register('./sw2/sw2.js', { scope: './sw2' })
    .then(function (reg) {
      console.log('success', reg);
    })
}
复制代码

兼容性

在这里插入图片描述
从这张图中,我们可以看到 IE 和 Opera Mini 全面扑街,而主流浏览器中 Edge 17以下不支持,Safair 和 IOS Safair 刚刚开始支持,而火狐和 Chrome 支持良好。所以大家可以放心的使用,不过最好还是做一下判断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值