繁体   English   中英

Service Worker:如何在服务器上更改文件时更新缓存?

[英]Service Worker: how to update the cache when files changed on the server?

你使用什么缓存策略? 我阅读了脱机食谱,最简单的策略是缓存静态内容,遗漏API调用。

这个策略看起来像这样:

  1. 检查请求是否已在缓存中
  2. 如果没有将请求,响应对添加到缓存
  3. 回复

如果在服务器端文件已更改,如何更新缓存? 目前,客户端始终获得缓存结果。

这是我的缓存策略的代码:

 // You will need this polyfill, at least on Chrome 41 and older. importScripts("serviceworker-cache-polyfill.js"); var VERSION = 1; var CACHES = { common: "common-cache" + VERSION }; // an array of file locations we want to cache var filesToCache = [ "font-cache.html", "script.js", ]; var neededFiles = [ "index.html" ]; var errorResponse = function() { return new Response([ "<h2>Failed to get file</h2>", "<p>Could not retrive response from cache</p>" ].join("\\n"), 500 ); }; var networkFetch = function(request) { return fetch(request).then(function(response) { caches.open(CACHES["common"]).then(function(cache) { return cache.put(request, response); }); }).catch(function() { console.error("Network fetch failed"); return errorResponse(); }); } this.addEventListener("install", function(evt) { evt.waitUntil( caches.open(CACHES["common"]).then(function(cache) { // Cache before cache.addAll(filesToCache); return cache.addAll(neededFiles); }) ); }); this.addEventListener("activate", function(event) { var expectedCacheNames = Object.keys(CACHES).map(function(key) { return CACHES[key]; }); console.log("Activate the worker"); // Active worker won"t be treated as activated until promise resolves successfully. event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (expectedCacheNames.indexOf() === -1) { console.log( "Deleting out of date cache:", cacheName); return caches.delete(cacheName); } }) ); }) ); }); self.addEventListener("fetch", function(event) { console.log("Handling fetch event for", event.request.url); event.respondWith( // Opens Cache objects caches.open(CACHES["common"]).then(function(cache) { return cache.match(event.request).then(function( response) { if (response) { console.log("Found response in cache", response); return response; } else { return networkFetch(event.request); } }).catch(function(error) { // Handles exceptions that arise from match() or fetch(). console.error( " Error in fetch handler:", error); return errorResponse(); }); }) ); }); 

你可能会熟悉Jeff Posnick的优秀解决方案 - sw-precache
使用的策略是:

  1. Gulp正在生成带校验和的Service Worker文件
  2. 服务工作者已注册(使用自己的校验和)
  3. 如果添加/更新了文件,则SW文件会更改
  4. 下次访问时,SW检查其校验和是否不同,因此它会再次使用更新的文件进行自我注册

您可以以任何您想要的方式使用后端自动执行此流程:)

他在本文对此进行了更好的描述

这是我用来缓存的代码。 它获取资源和缓存并提供服务。

this.addEventListener("fetch", function(event) {
  event.respondWith(
    fetch(event.request).then(function(response) {
      return caches.open("1").then(function(cache) {
        return cache.put(event.request, response.clone()).then(function() {
          return response
        })
      })
    }).catch(function() {
      return caches.match(event.request)
    })
  )
})

您必须更改您的Service Worker文件。 根据服务工作者简介

当用户导航到您的站点时,浏览器会尝试重新下载在后台定义服务工作者的脚本文件。 如果服务工作文件中的字节与现有文件的差异,则认为它是“新的”。

因此,即使您只需要更改静态资源,也必须更新服务工作文件,以便注册更新缓存的新服务工作程序。 (您将确保在activate处理程序中删除任何以前的缓存。)@ Karol Klepacki的答案提出了一种自动化方法。

或者,您可以在服务工作者本身中实现逻辑,以定期检查缓存资源的更改并适当更新条目。

暂无
暂无

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

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