问题
Everytime I make any change to the index.html with my angular project, Serviceworker never gets updated and always serves the old cached version on index.html. How do I fix this (Also, there is no caching at the server end as well as browser)
Here is my ngsw-config file
{
"index": "/index.html",
"assetGroups": [{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/manifest.json"
],
"versionedFiles": [
"/*.bundle.css",
"/*.bundle.js",
"/*.chunk.js"
]
}
}, {
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**"
]
}
}]
}
My response headers for the request:
Any idea how to get this fixed?
Thanks
回答1:
I think the problem is in the ngsw-config. The .css and .js entries under versionedFiles
may not match the .css and .js files in the dist folder if they don't have .bundle or .chunk in their names. In more recent versions of Angular those entries were replaced with "/*.js"
and "/*.css"
, and the files in the dist folder don't have .bundle or .chunk when building for production.
So, the problem actually is that the .js and .css files are not being cached and whenever the files on the server are updated, the app no longer finds them and the browser throws an error (because it returns the index.html) before the service worker can load the "cached" files, detect the changes and update the files.
In Angular 6, versionedFiles
behaves the same as files
and was deprecated. So, your ngsw-config.json should look like this:
{
"index": "/index.html",
"assetGroups": [{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": [
"/favicon.ico",
"/index.html",
"/manifest.json",
"/*.css",
"/*.js"
]
}
}, {
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**"
]
}
}]
}
回答2:
You can force the service worker to delete all previous SW caches (index.html too) with a code like this in the service worker:
const DIRTY_CACHE = 'application-version-number-or-whatever';
self.addEventListener('install', () => {
// Skip over the "waiting" lifecycle state, to ensure that our
// new service worker is activated immediately, even if there's
// another tab open controlled by our older service worker code.
self.skipWaiting();
});
self.addEventListener('activate', event => {
self.registration.unregister();
event.waitUntil(
caches
.keys()
.then(cacheNames =>
cacheNames.filter(cacheName => cacheName.indexOf(DIRTY_CACHE) !== -1),
)
.then(cachesToDelete =>
Promise.all(
cachesToDelete.map(cacheToDelete => caches.delete(cacheToDelete)),
),
)
.then(() => self.clients.claim()),
);
});
A more detailed explanation can be found in this article
Maybe is not the best strategy, but resolves the issue, probably due to a bad expires header.
来源:https://stackoverflow.com/questions/49142968/caching-of-index-html-in-angular-service-worker