Service Worker:当服务器上的文件发生变化时,如何更新缓存
Service Worker: how to update the cache when files changed on the server?
您使用什么缓存策略?我读了离线烹饪书,最简单的策略是缓存静态内容,并忽略API调用。
这个策略看起来像这样:
- 检查请求是否已经在缓存中
- 如果不添加请求,响应对缓存 <
- 返回响应/gh>
如何更新缓存,如果在服务器端文件已更改?目前客户端总是得到缓存的结果。
下面是我的缓存策略代码:
// 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。
这里使用的策略是:
- Gulp生成带有校验和的Service Worker文件
- Service Worker已注册(带有自己的校验和)
- 如果文件被添加/更新,SW文件更改
- 在下次访问时,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文件。根据Introduction to Service Worker:
当用户导航到你的站点时,浏览器会尝试在后台重新下载定义service worker的脚本文件。如果service worker文件中有一个字节的差异,它就会认为它是'new'。
所以即使你只需要改变静态资源,你也必须更新你的service worker文件,以便注册一个新的service worker来更新缓存。(你要确保在你的activate
处理程序中删除任何以前的缓存)@Karol Klepacki的回答建议了一种自动化的方法。
或者,你可以在service worker本身中实现逻辑,定期检查缓存的资源是否有变化,并适当地更新条目。
相关文章:
- 强制浏览器更新缓存的HTML5视频对象
- 通过javascript清除并更新html5应用程序缓存
- 如何在动态表更新后刷新整个表排序缓存
- 如何更新浏览器'使用Ajax将html添加到页面后的缓存
- 通过应用程序缓存仅更新一个文件
- 如何在脱机工作时将数据写入和更新 HTML5 缓存的网页
- 缓存清单更新网页(如果联机)
- Vaadin @Javascript :清除更新的JS文件的缓存
- Cordova应用程序自动同步/更新Web内容(.js文件),如果更新版本可用,否则使用缓存版本
- 更改清单时 Html5 缓存不更新
- 为对事件更新文件的相同调用刷新浏览器缓存
- 使用数据URI快速更新图像会导致缓存、内存泄漏
- windows 8由于Javascript应用程序中的xml缓存而无法更新应用程序数据
- 是否在应用程序缓存清单更新时更新所有文件?或者只是改变了的那些
- 如果正在更新应用程序缓存,请阻止ajax调用
- 缓存某个地方阻止Django 1.6中的更新模板
- 缓存——一次用查询字符串更新多个js文件
- 网站更新缓存
- 在用form卸载javascript之前更新缓存
- Service Worker:当服务器上的文件发生变化时,如何更新缓存