简体   繁体   English

Service Worker - 如何知道缓存是否被清除?

[英]Service Worker - how to know whether cache cleared?

I'm trying to implement a basic service worker to assure that users of my simple web app have the latest code.我正在尝试实现一个基本的服务人员,以确保我的简单 web 应用程序的用户拥有最新的代码。 So when I update html, js, or css files I can increment the cachename in the service worker file and prompt users to refresh, clear their cache, and get the latest code.因此,当我更新 html、js 或 ZC7A62​​8CBA22E28EB17B5F5C6AE2A266AZ 文件时,我可以增加 service worker 文件中的缓存名称并提示用户刷新、清除缓存并获取最新代码。

Until now I've relied on hacky ways to update javascript files (including a parameter in the referring URL: /javascript-file.js?v=1).到目前为止,我一直依靠 hacky 方法来更新 javascript 文件(包括引用 URL 中的参数:/javascript-file.js?v=1)。

The with the service worker code below seem unpredictable: sometimes small changes to JS or CSS are reflected after I increment the cachename (code below).下面的服务工作者代码似乎不可预测:有时在我增加缓存名称(下面的代码)后,对 JS 或 CSS 的微小更改会反映出来。 Sometimes the changes are reflected without incrementing the cachename, which suggests the code is ALWAYS pulling from the network (wasting resources).有时更改会在不增加缓存名称的情况下反映,这表明代码总是从网络中提取(浪费资源)。

How can you troubleshoot which version of files the code is using and whether the service worker is using cached or network versions?如何解决代码使用的文件版本以及服务工作者使用的是缓存版本还是网络版本? Am I not understanding the basic model for using service workers to achieve this goal?我是否不了解使用服务人员实现此目标的基本 model ?

Any help appreciated.任何帮助表示赞赏。

serv-worker.js (in root): serv-worker.js(在根目录下):

console.log('Start serv-worker.js');

const cacheName = '3.2121';

var urlsToCache = [
  'home.html',
  'home-js.js', 
  'web-bg.js', 
  'css/main.css',
  'css/edit-menus.css'
];

self.addEventListener('install', event => {
  console.log('Install event...', urlsToCache);
  event.waitUntil(
    caches.open(cacheName)
      .then(function(cache) {
        console.log('Opened cache', cacheName);
        return cache.addAll(urlsToCache);
      })
    );
});

//  Network first.
self.addEventListener('fetch', (event) => {
  // Check the cache first
  // If it's not found, send the request to the network
  // event.respondWith(
  //   caches.match(event.request).then(function (response) {
  //     return response || fetch(event.request).then(function (response) {
  //       return response;
  //     });
  //   })
  // );
  event.respondWith(async function() {
    try {
      console.log('aPull from network...', event.request);
      return await fetch(event.request);
    } catch (err) {
      console.log('aPull from cache...', event.request);
      return caches.match(event.request);
    }
  }());
});

self.addEventListener('message', function (event) {
  console.log('ServiceWorker cache version: ', cacheName, event);
  console.log('Received msg1: ', event.data);
  if (event.data.action === 'skipWaiting') {
    console.log('ccClearing cache: ', cacheName);
    // caches.delete('1.9rt1');     //  hardcode old one
    // caches.delete(cacheName);     //  actually removes cached versions
    caches.keys().then(function(names) {
      for (let name of names)
          caches.delete(name);
    });
    self.skipWaiting();
  }
});

Code in web-bg.js, which home.html references: web-bg.js 中的代码,其中 home.html 引用:

function servWorker(){
  let newWorker;

  function showUpdateBar() {
    console.log('Show the update mssgg...ddddd');
    $('#flexModalHeader').html('AP just got better!');
    $('#flexModalMsg').html("<p>AP just got better. Learn about <a href='https://11trees.com/support/release-notes-annotate-pro-web-editor/'>what changed</a>.<br><br>Hit Continue to refresh.</p>");
    $('#flexModalBtn').html("<span id='updateAPbtn'>Continue</span>");
    $('#flexModal').modal('show');
  }

  // The click event on the pop up notification
  $(document).on('click', '#updateAPbtn', function (e) {
    console.log('Clicked btn to refresh...');
    newWorker.postMessage({ action: 'skipWaiting' });
  });

  if ('serviceWorker' in navigator) {
    console.log('ServiceWORKER 1234');
    navigator.serviceWorker.register(baseDomain + 'serv-worker.js').then(reg => {
      console.log('In serviceWorker check...', reg);
      reg.addEventListener('updatefound', () => {
        console.log('A wild service worker has appeared in reg.installing!');
        newWorker = reg.installing;
        newWorker.addEventListener('statechange', () => {
          // Has network.state changed?
          console.log('SSState is now: ', newWorker.state);
          switch (newWorker.state) {
            case 'installed':
              if (navigator.serviceWorker.controller) {
                // new update available
                console.log('Detected service worker update...show update...');
                showUpdateBar();
              }
              // No update available
              break;
          }
        });
      });
    });

    let refreshing;
    navigator.serviceWorker.addEventListener('controllerchange', function (e) {
      console.log('a1111xxxListen for controllerchange...', e);''
      if (refreshing) return;
      console.log('Refresh the page...');
      window.location.reload();
      refreshing = true;
    });

  }   //   End serviceworker registration logic
  return;
}   //  END serv-worker

You've commented out the section for /// Check the cache first and then below that the try/catch statement again pulls from the network and falls back to the cache.您已经注释掉了/// Check the cache first的部分,然后在下面的 try/catch 语句再次从网络中提取并回退到缓存。

Uncomment this section of code and see if you're loading from the cache first.取消注释这部分代码,看看您是否首先从缓存中加载。

  // event.respondWith(
  //   caches.match(event.request).then(function (response) {
  //     return response || fetch(event.request).then(function (response) {
  //       return response;
  //     });
  //   })
  // );

Don't forget that even if you request from the network from the service worker the browser will still use it's own internal cache to serve data.不要忘记,即使您从服务工作者的网络请求,浏览器仍将使用它自己的内部缓存来提供数据。 How long the data stays in the browser's cache depends on the expiration headers being sent by the server.数据在浏览器缓存中的停留时间取决于服务器发送的过期标头。

When using expires, it's still a fairly common solution to do something like:使用 expires 时,它仍然是一个相当常见的解决方案,例如:

  • index.html - expires after an hour. index.html - 一小时后到期。 Has script/css tags that call out file names with?v=xyz具有使用?v=xyz 调用文件名的脚本/css 标签
  • /resources - folder that holds js and css. /resources - 包含 js 和 ZC7A62​​8CBA22E28EB17B5F5C6AE2A266AZ 的文件夹。 This folder has a very long expiration time.这个文件夹的过期时间很长。 But that long expiration is short circuited by changing the?v=xyz in index.html但是通过更改 index.html 中的?v=xyz 可以缩短长期到期时间

I've used the above successfully in Progressive Web Apps (PWAs).我已经在 Progressive Web 应用程序 (PWA) 中成功使用了上述内容。 But it is a little painful when debugging.但是调试的时候有点痛苦。 The best option here is to manually clear out the cache and service worker from Dev Tools \ Application, if you're in Chrome.如果您在 Chrome 中,最好的选择是从 Dev Tools\Application 手动清除缓存和服务工作者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM