簡體   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