如何在登录后强制更新 PWA 缓存 [JS]?
How to force update PWA cache after login [JS]?
我有一个简单的论坛,我想离线使用。我有一个动态和静态缓存。静态缓存会填充安装事件和动态缓存,因为您会一直查看帖子。
问题是它缓存的页面包括 header 如果您已登录,则您有一个 link 到配置文件,如果您没有登录,则 link 到注册页面。
登录后它仍然显示注册 link 而不是个人资料 link。修复它的方法是刷新缓存?
有没有办法做到这一点,或者是否有其他解决此类问题的方法(除了网络优先方法之外)?
我是 PWA 的新手,找不到任何有用的提示。
我的服务人员看起来像这样:
const staticCacheName = "ScroocCacheV1";
const dynamicCacheName = "ScroocDynamicCacheV1";
const assets = [
'/',
'/css/main_styles.css',
'/js/ui.js',
'/about',
'/policies',
'/register',
'/createTopic',
'/stats',
'/proposals',
];
const limitCacheSize = (name, size) => {
caches.open(name).then(cache => {
cache.keys().then(keys => {
if(keys.length > size) {
cache.delete(keys[0]).then(limitCacheSize(name, size));
}
});
});
}
const dynamicCacheLimit = 18;
// Install service worker
self.addEventListener('install', evt => {
evt.waitUntil(
caches.open(staticCacheName).then(cache => {
cache.addAll(assets);
})
);
});
// Activate event
self.addEventListener('activate', evt => {
evt.waitUntil(
caches.keys().then(keys => {
keys.map((key => {
if (key !== staticCacheName && key !== dynamicCacheName) {
return caches.delete(key); //Deleting the old cache (cache v1)
}
}))
})
)
});
// Intercept fetch
self.addEventListener('fetch', evt => {
evt.respondWith(
fetch(evt.request).then(fetchRes => {
return caches.open(dynamicCacheName).then(cache => {
return caches.match(evt.request).then(function(result) {
if (result) {
return result;
} else {
cache.put(evt.request.url, fetchRes.clone());
limitCacheSize(dynamicCacheName, dynamicCacheLimit);
return fetchRes;
}
});
});
}).catch(function() {
return caches.match(evt.request).catch((error) => {
console.log(error)
return caches.match('/img/fallbackImage.png');
});
})
);
});
The way to fix it would be to refresh the cache?
没错,假设您缓存了路径 /login
,Service Worker 将始终根据您的代码显示缓存在该路径下的内容。
Is there a way to do this or is there some other fix for this type of issue(besides network first approach)?
这并不是真正需要“修复”的东西,您所描述的是某种预期的行为。
解决这个问题有几种方法,网络优先只是一种方法:
- 使用a message在登录时更新缓存
- 在用户登录时使用不同的 url 或 url 查询等部分来跳过缓存
- 根据用户状态隐藏客户端不需要的UI
可能还有很多。
这对我有用!
在尝试清空缓存之前,必须先成功安装服务工作者。因此,为了记录在案,您的 sw.js 文件应以通常的
开头
self.addEventListener("install", ...etc
现在我们要开始清理了。创建一个变量来存储您想要的缓存的名称 purge/update (使定位不同的缓存更容易)
var TargetCache= 'NameOfCacheToClean';
接下来,添加一个每次激活 service worker 时触发的 EventListener (activate-event 出现在页面 reload/refresh 上)
self.addEventListener('activate', event =>
{
const currentCaches = [TargetCache];
event.waitUntil
(
caches.keys()
.then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));})
.then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);})); })
.then(() => self.clients.claim())
);
});
只是 in-case,我通常会在 fetch-requests 清除旧缓存的代码之后添加拦截传出的事件侦听器。
self.addEventListener('fetch', function(event) {...etc
我有一个简单的论坛,我想离线使用。我有一个动态和静态缓存。静态缓存会填充安装事件和动态缓存,因为您会一直查看帖子。 问题是它缓存的页面包括 header 如果您已登录,则您有一个 link 到配置文件,如果您没有登录,则 link 到注册页面。 登录后它仍然显示注册 link 而不是个人资料 link。修复它的方法是刷新缓存?
有没有办法做到这一点,或者是否有其他解决此类问题的方法(除了网络优先方法之外)? 我是 PWA 的新手,找不到任何有用的提示。
我的服务人员看起来像这样:
const staticCacheName = "ScroocCacheV1";
const dynamicCacheName = "ScroocDynamicCacheV1";
const assets = [
'/',
'/css/main_styles.css',
'/js/ui.js',
'/about',
'/policies',
'/register',
'/createTopic',
'/stats',
'/proposals',
];
const limitCacheSize = (name, size) => {
caches.open(name).then(cache => {
cache.keys().then(keys => {
if(keys.length > size) {
cache.delete(keys[0]).then(limitCacheSize(name, size));
}
});
});
}
const dynamicCacheLimit = 18;
// Install service worker
self.addEventListener('install', evt => {
evt.waitUntil(
caches.open(staticCacheName).then(cache => {
cache.addAll(assets);
})
);
});
// Activate event
self.addEventListener('activate', evt => {
evt.waitUntil(
caches.keys().then(keys => {
keys.map((key => {
if (key !== staticCacheName && key !== dynamicCacheName) {
return caches.delete(key); //Deleting the old cache (cache v1)
}
}))
})
)
});
// Intercept fetch
self.addEventListener('fetch', evt => {
evt.respondWith(
fetch(evt.request).then(fetchRes => {
return caches.open(dynamicCacheName).then(cache => {
return caches.match(evt.request).then(function(result) {
if (result) {
return result;
} else {
cache.put(evt.request.url, fetchRes.clone());
limitCacheSize(dynamicCacheName, dynamicCacheLimit);
return fetchRes;
}
});
});
}).catch(function() {
return caches.match(evt.request).catch((error) => {
console.log(error)
return caches.match('/img/fallbackImage.png');
});
})
);
});
The way to fix it would be to refresh the cache?
没错,假设您缓存了路径 /login
,Service Worker 将始终根据您的代码显示缓存在该路径下的内容。
Is there a way to do this or is there some other fix for this type of issue(besides network first approach)?
这并不是真正需要“修复”的东西,您所描述的是某种预期的行为。
解决这个问题有几种方法,网络优先只是一种方法:
- 使用a message在登录时更新缓存
- 在用户登录时使用不同的 url 或 url 查询等部分来跳过缓存
- 根据用户状态隐藏客户端不需要的UI
可能还有很多。
这对我有用!
在尝试清空缓存之前,必须先成功安装服务工作者。因此,为了记录在案,您的 sw.js 文件应以通常的
开头self.addEventListener("install", ...etc
现在我们要开始清理了。创建一个变量来存储您想要的缓存的名称 purge/update (使定位不同的缓存更容易)
var TargetCache= 'NameOfCacheToClean';
接下来,添加一个每次激活 service worker 时触发的 EventListener (activate-event 出现在页面 reload/refresh 上)
self.addEventListener('activate', event =>
{
const currentCaches = [TargetCache];
event.waitUntil
(
caches.keys()
.then(cacheNames => {return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));})
.then(cachesToDelete => {return Promise.all(cachesToDelete.map(cacheToDelete => {return caches.delete(cacheToDelete);})); })
.then(() => self.clients.claim())
);
});
只是 in-case,我通常会在 fetch-requests 清除旧缓存的代码之后添加拦截传出的事件侦听器。
self.addEventListener('fetch', function(event) {...etc