• 关于Service Worker


    Service Worker

    含义

    Service Worker 首先是一个运行在后台的 Worker 线程,然后它会长期运行,充当一个服务,很适合那些不需要网页或用户互动的功能。它的最常见用途就是拦截和处理网络请求。

    Service Worker 是一个后台运行的脚本,充当一个代理服务器,拦截用户发出的网络请求,比如加载脚本和图片。Service Worker 可以修改用户的请求,或者直接向用户发出回应,不用联系服务器,这使得用户可以在离线情况下使用网络应用。它还可以在本地缓存资源文件,直接从缓存加载文件,因此可以加快访问速度。

    1. if ('serviceWorker' in navigator) {
    2. window.addEventListener('load', function() {
    3.  `navigator.serviceWorker.register('/service-worker.js');`
      
    4. });
    5. }

    上面代码确认浏览器支持 Service Worker 以后,会注册一个 Service Worker。

    为了节省内存,Service worker 在不使用的时候是休眠的。它也不会保存数据,所以重新启动的时候,为了拿到数据,最好把数据放在 IndexedDb 里面。

    Service Worker 是事件驱动的。

    下面是拦截请求的例子。

    1. self.addEventListener('fetch', (event) => {
    2. event.waitUntil(
    3.  `if (event.request.url.includes('/product') {`
      
    4.    `let productId = event.data.productId`
      
    5.    `let productCount = getProductData(productId)`
      
    6.    `indexedDB.open('store', 1, (db) => {`
      
    7.      `let productStore = db.createObjectStore('products', { keyPath: 'id' })`
      
    8.      `productStore.put({ id: productId, count: ++productCount })`
      
    9.    `})`
      
    10.  `})`
      
    11. )
    12. })

    Service Worker 不能直接操作 DOM。

    使用步骤

    登记

    使用 service worker 的第一步,就是告诉浏览器,需要注册一个 service worker 脚本。

    1. navigator.serviceWorker.register('sw.js'.then(() => {
    2. console.info('注册成功')
    3. }).catch((err) => {
    4. console.error('注册失败')
    5. })

    上面代码的sw.js就是需要浏览器注册的 service worker 脚本。注意,这个脚本必须与当前网址同域,service worker 不支持跨与脚本。另外,sw.js必须是从 HTTPS 协议加载的。

    默认情况下,Service worker 只对根目录/生效,如果要改变生效范围,可以运行下面的代码。

    1. navigator.serviceWorker.register(
    2. '/service-worker.js',
    3. { scope: '/products/fashion' }
    4. )

    安装

    一旦登记成功,接下来都是 service worker 脚本的工作。下面的代码都是写在 service worker 脚本里面的。

    登记后,就会触发install事件。service worker 脚本需要监听这个事件。

    1. self.addEventListener('install', event => {

    2. event.waitUntil(() => console.info('安装完成'))

    3. })

    event.waitUntil()方法为事件完成后指定回调函数。

    1. self.addEventListener('install', (event) => {
    2.  `let CACHE_NAME = 'xyz-cache'`
      
    3.  `let urlsToCache = [`
      
    4.      `'/',`
      
    5.      `'/styles/main.css',`
      
    6.      `'/scripts/bundle.js'`
      
    7.  `]`
      
    8.  `event.waitUntil(`
      
    9.      `caches.open(CACHE_NAME)`
      
    10.      `.then (cache => cache.addAll(urlsToCache))`
      
    11.  `)`
      
    12. })

    激活

    安装完成后,service worker 就会等待激活。

    1. self.addEventListener('activate', (event) => {

    2.  `let cacheWhitelist = ['products-v2']`
      
    3.  `event.waitUntil(`
      
    4.      `caches.keys().then (cacheNames => {`
      
    5.          `return Promise.all(`
      
    6.              `cacheNames.map( cacheName => {`
      
    7.                  `if (cacheWhitelist.indexOf(cacheName) === -1) {`
      
    8.                      `return caches.delete(cacheName)`
      
    9.                  `}`
      
    10.              `})`
      
    11.          `)`
      
    12.      `})`
      
    13.  `)`
      
    14. })

    Service Worker 与网页的通信

    1. self.addEventListener('activate', (event) => {
    2.  `event.waitUntil(`
      
    3.      `self.clients.matchAll().then ( (client) => {`
      
    4.          `client.postMessage({`
      
    5.              `msg: 'Hey, from service worker! I\'m listening to your fetch requests.',`
      
    6.              `source: 'service-worker'`
      
    7.          `})`
      
    8.      `})`
      
    9.  `)`
      
    10. })

    上面代码中,Service Worker 监听activate事件,然后向客户端发送一条信息。

    客户端需要部署消息监听代码。

    1. this.addEventListener('message', (data) => {
    2.  `if (data.source == 'service-worker') {`
      
    3.      `console.log(data.msg)`
      
    4.  `}`
      
    5. })
  • 相关阅读:
    FZU Problem 2150 Fire Game
    HTTP协议认识
    GitHub
    设计模式学习笔记(一)——面向对象设计模式与原则
    信息安全系统设计基础第九周学习总结
    信息安全系统设计基础第八周期中总结
    家庭作业二
    信息安全系统设计基础第七周学习总结
    家庭作业
    信息安全系统设计基础第六周学习总结
  • 原文地址:https://www.cnblogs.com/axl234/p/16307066.html
Copyright © 2020-2023  润新知