Service Worker的学习

本文深入讲解ServiceWorker的工作原理,包括注册、缓存配置、拦截请求及页面通信等关键环节,为开发者提供全面的ServiceWorker应用指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Service Worker的学习

限制:只有在https协议下 Service Worker 才能够被注册,本地调试可用localhost。

Service Worker 的生命周期

Service Worker 的生命周期

一、注册service worker

if (navigator.serviceWorker) { // 判断是否支持service worker
  // 注册service worker
  navigator.serviceWorker.register('./service-worker.js', // service worker 配置文件的位置
  {
    scope: './' // 作用域为当前目录
  }).then(function (reg) {
    console.log(reg);
  }).catch(function (e) {
    console.log(e);
  })
} else {
  alert('Service Worker is not supported!');
} 

二、缓存文件 的配置

// service-worker.js
self.addEventListener('install', function (e) {
  e.waitUntil(
    caches.open('app-v1') // 打开缓存
	    .then(function (cache) {
	      console.log('open cache')
	      return cache.addAll([ // 缓存所有不需要经常更新的文件
	        './app.js',
	        './main.css',
	        './serviceWorker.html'
	      ])
	    })
  )
})

三、拦截请求 的配置

// service-worker.js
self.addEventListener('fetch', function (e) {
  e.respondWith(
    caches.match(e.request).then(function (res) { // 先在cacheStorage中寻找资源
      if (res) { // 若cacheStorage中有缓存资源,则直接返回资源
        return res
      } else { // 若cacheStorage中无匹配的缓存资源,则向网络发起请求
         // 通过fetch方法去先网络发起请求
        fetch(资源uri).then(function (res) {
          if (res) {
            对于新请求到的资源存储到cacheStorage中
          } else {
            提供用户提示
          }
        })
      }
    })
  )
})

四、页面通信 的配置

通过 navigator.serviceWorker.controller.postMessage() 来通信
eg:

<!--msg-demo.html-->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>msg-demo</title>
</head>

<body>
  <ul id="msg-box">

  </ul>
  <input type="text" id="msg-input" />
  <button id="send-msg-button">发送</button>
  <script src="./msgapp.js"></script>
</body>

</html>
// msgapp.js
if (navigator.serviceWorker) {
  var sendBtn = document.getElementById('send-msg-button'); // 获取button元素
  var msgInput = document.getElementById('msg-input'); // 获取input框元素
  var msgBox = document.getElementById('msg-box'); // 获取ul列表元素

  // 监听数据的接收
  navigator.serviceWorker.addEventListener('message', function (event) {
    // 当从serviceWorker获取到数据的时候,就显示在页面上
    msgBox.innerHTML = msgBox.innerHTML + ('<li>' + event.data.message + '</li>');
  })

  // 点击发送按钮发送input框中的内容给serviceWorker
  sendBtn.addEventListener('click', function () {
    // 主页面发送信息到serviceWorker,navigator.serviceWorker.controller在serviceWorker未注册成功前为空
    navigator.serviceWorker.controller.postMessage(msgInput.value);
  })

  // 注册serviceWorker
  navigator.serviceWorker.register('./msgsw.js', // service worker 配置文件的位置
  {
    scope: './' // 作用域为当前目录
  }).then(function (reg) {
    console.log(reg);
  }).catch(function (e) {
    console.log(e);
  })
} else {
  alert('Service Worker is not supported!');
}
// msgsw.js
// serviceWorker监听数据的接收
self.addEventListener('message', function (event) {
  // 接收到数据后广播到除了发送源以外的所有客户端
  // self.clients.matchAll() 匹配所有这个serviceWorker下的客户端
  var promise = self.clients.matchAll().then(function (clientList) {
    // 获取发送源的唯一标志ID
    var senderID = event.source ? event.source.id : 'unknown'
    clientList.forEach(function (client) {
      if (client.id === senderID) { // 当客户端ID===发送源ID,则不serviceWorker发送数据到页面
        return
      } else {
        // 向其他页面发送数据
        client.postMessage({
          client: senderID,
          message: event.data
        })
      }
    })
  })
  event.waitUntil(promise) // waitUntil等待一个promise事件
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值