Service Worker 有什么方法可以在每次网站更新时删除设备上的缓存吗?
Is there any way that service worker can delete the cache on device on every website update?
每当我对使用 Laravel 开发的网站进行任何更新时,我都必须删除浏览器缓存以反映更改。这既适用于在本地主机上工作,也适用于我将其部署在服务器上时。有没有什么方法可以使这个过程自动化,或者通过服务工作者在每次新更新后删除缓存?
这是我的serviceworker.js
var staticCacheName = "pwa-v" + new Date().getTime();
var filesToCache = [
'/offline.html',
'/css/style.css',
'/js/app.js',
];
// Cache on install
self.addEventListener("install", event => {
this.skipWaiting();
event.waitUntil(
caches.open(staticCacheName)
.then(cache => {
return cache.addAll(filesToCache);
})
)
});
// Clear cache on activate
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames
.filter(cacheName => (cacheName.startsWith("pwa-")))
.filter(cacheName => (cacheName !== staticCacheName))
.map(cacheName => caches.delete(cacheName))
);
})
);
});
// Serve from Cache
self.addEventListener("fetch", event => {
event.respondWith(
caches.match(event.request)
.then(response => {
return response || fetch(event.request);
})
.catch(() => {
return caches.match('/offline.html');
})
)
});
这是我用来删除陈旧资产的片段,无需人工干预。
function deleteStaleAssets(url, asset) {
caches.open(CACHE_NAME).then(function(cache) {
cache.keys().then(function(keys) {
let cc = keys.filter(function(req) {
if(req.url.includes(asset) && req.url !== url) {
return true;
}
});
cc.forEach(function(r) {
cache.delete(r);
});
});
});
}
function onFetch(event) {
var assets = ['/assets/application', 'assets/spree/frontend/all'];
var asset = assets.find(function(asset) {
return event.request.url.includes(asset);
});
if(asset) {
event.respondWith(async function() {
const cache = await caches.open(CACHE_NAME);
const cachedResponse = await cache.match(event.request);
const networkResponsePromise = fetch(event.request);
event.waitUntil(async function() {
const networkResponse = await networkResponsePromise;
deleteStaleAssets(event.request.url, asset);
await cache.put(event.request, networkResponse.clone());
}());
// Returned the cached response if we have one, otherwise return the network response.
return cachedResponse || networkResponsePromise;
}());
}
else {
event.respondWith(
// try to return untouched request from network first
fetch(event.request).catch(function() {
// if it fails, try to return request from the cache
return caches.match(event.request).then(function(response) {
if (response) {
return response;
}
// if not found in cache, return default offline content for navigate requests
if (event.request.mode === 'navigate' ||
(event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html'))) {
return caches.match('/offline.html');
}
})
})
);
}
}
每当我对使用 Laravel 开发的网站进行任何更新时,我都必须删除浏览器缓存以反映更改。这既适用于在本地主机上工作,也适用于我将其部署在服务器上时。有没有什么方法可以使这个过程自动化,或者通过服务工作者在每次新更新后删除缓存?
这是我的serviceworker.js
var staticCacheName = "pwa-v" + new Date().getTime();
var filesToCache = [
'/offline.html',
'/css/style.css',
'/js/app.js',
];
// Cache on install
self.addEventListener("install", event => {
this.skipWaiting();
event.waitUntil(
caches.open(staticCacheName)
.then(cache => {
return cache.addAll(filesToCache);
})
)
});
// Clear cache on activate
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames
.filter(cacheName => (cacheName.startsWith("pwa-")))
.filter(cacheName => (cacheName !== staticCacheName))
.map(cacheName => caches.delete(cacheName))
);
})
);
});
// Serve from Cache
self.addEventListener("fetch", event => {
event.respondWith(
caches.match(event.request)
.then(response => {
return response || fetch(event.request);
})
.catch(() => {
return caches.match('/offline.html');
})
)
});
这是我用来删除陈旧资产的片段,无需人工干预。
function deleteStaleAssets(url, asset) {
caches.open(CACHE_NAME).then(function(cache) {
cache.keys().then(function(keys) {
let cc = keys.filter(function(req) {
if(req.url.includes(asset) && req.url !== url) {
return true;
}
});
cc.forEach(function(r) {
cache.delete(r);
});
});
});
}
function onFetch(event) {
var assets = ['/assets/application', 'assets/spree/frontend/all'];
var asset = assets.find(function(asset) {
return event.request.url.includes(asset);
});
if(asset) {
event.respondWith(async function() {
const cache = await caches.open(CACHE_NAME);
const cachedResponse = await cache.match(event.request);
const networkResponsePromise = fetch(event.request);
event.waitUntil(async function() {
const networkResponse = await networkResponsePromise;
deleteStaleAssets(event.request.url, asset);
await cache.put(event.request, networkResponse.clone());
}());
// Returned the cached response if we have one, otherwise return the network response.
return cachedResponse || networkResponsePromise;
}());
}
else {
event.respondWith(
// try to return untouched request from network first
fetch(event.request).catch(function() {
// if it fails, try to return request from the cache
return caches.match(event.request).then(function(response) {
if (response) {
return response;
}
// if not found in cache, return default offline content for navigate requests
if (event.request.mode === 'navigate' ||
(event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html'))) {
return caches.match('/offline.html');
}
})
})
);
}
}