如何用 ServiceWorker 生命周期替换 appcache 生命周期事件
How to replace appcache lifecycle event with ServiceWorker lifecycle
我正在尝试在我的离线工作应用程序中将 appcache 更改为 serviceworker。我已从 html 页面删除清单标签并创建 serviceworker.js 作为生命周期事件。但是,appcache 事件的使用如下所示:
function framework(){
this.appCache = window.applicationCache;
//more other codes
}
var fw = new framework();
现在,生命周期事件是这样检查的:
if (fw.appCache) {
/* Checking for an update. Always the first event fired in the sequence.*/ fw.appCache.addEventListener('checking', handleCacheEvent, false);
/* An update was found. The browser is fetching resources.*/ fw.appCache.addEventListener('downloading', handleCacheEvent, false);
/* Fired if the manifest file returns a 404 or 410.
This results in the application cache being deleted. */ fw.appCache.addEventListener('obsolete', handleCacheEvent, false);
/* The manifest returns 404 or 410, the download failed,
or the manifest changed while the download was in progress.*/ fw.appCache.addEventListener('error', handleCacheError, false);
/* Fired for each resource listed in the manifest as it is being fetched.*/fw.appCache.addEventListener('progress', handleProgressEvent, false);
/*Fired after the first cache of the manifest. */ fw.appCache.addEventListener('cached', function(event){handleCacheEvent(event);removeProcessing();$("#processingTextId").html("");}, false);
/* Fired after the first download of the manifest.*/ fw.appCache.addEventListener('noupdate', function(event){handleCacheEvent(event);removeProcessing(); $("#processingTextId").html("");}, false);
/* Fired when the manifest resources have been newly redownloaded. */ fw.appCache.addEventListener('updateready', function(e) {if (fw.appCache.status == fw.appCache.UPDATEREADY) {alert('Successful'); try{fw.appCache.swapCache();window.location.reload();} catch(err){}}}, false);
}
function handleCacheEvent(event) {$("#processingTextId").html(event.type);}
function handleProgressEvent(event) {$("#processingTextId").html("(" + event.loaded + " of "+ event.total +")");}
function handleCacheError(event) {$("#processingTextId").html("Cache failed to update!")
所以,我的问题是如何用服务工作者事件替换此事件。我的 serviceworker 已注册并正确缓存资产。现在,我在 index.html
中这样做
注册
<script type="text/javascript">
if('serviceWorker' in navigator){
navigator.serviceWorker.register('serviceworker.js')
.then(registration =>{
console.log('registration successful:',registration.scope);
})
.catch(err=>{
console.log('registration failed:',err);
});
}
</script>
我创建了单独的 serviceworker.js。
如何用serviceworker替换那些appcache事件?
在使用 Service Worker 时,您不会自动结束这些事件中的任何一个。此外,service worker 填充和更新缓存的模型 "open ended" 比 AppCache 多得多,因此将 service worker 缓存转换为等效的 AppCache 事件并不总是可能的。
不过,总的来说,有两件事可以提供帮助:
阅读 Service Worker Lifecycle. Some events that you might care about could be approximated by listening for equivalent changes to the service worker lifecycle. For instance, if you precache some URLs during service worker installation,然后新注册的服务工作者离开 installing
状态大致相当于 AppCache 清单完成缓存时的状态。类似地,如果您检测到先前注册的 service worker 何时有更新(并且该更新是由于要预缓存的 URL 列表发生更改),那么这大致对应于更新 AppCache 清单的时间。
如果您的服务人员使用 "runtime" 缓存,其中 URL 被添加到 fetch
处理程序内部的缓存中,您可以使用以下技术告诉您的客户端页面什么时候已缓存新项目,使用 postMessage()
进行通信。
您服务人员的一部分 JavaScript:
const cacheAddAndNotify = async (cacheName, url) => {
const cache = await caches.open(cacheName);
await cache.add(url);
const clients = await self.clients.matchAll();
for (const client of clients) {
client.postMessage({cacheName, url});
}
};
self.addEventListener('fetch', (event) => {
// Use cacheAddAndNotify() to add to your cache and notify all clients.
});
您网络应用程序的一部分 JavaScript:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.addEventListener('message', (event) => {
const {cacheName, url} = event.data;
// cacheName and url represent the entry that was just cached.
});
}
同样,您所听内容的具体细节以及您对此的反应方式实际上将取决于您在服务工作者中的逻辑。不要指望所有事件之间都有 1:1 映射。相反,将此迁移作为一个机会来思考您真正关心的与缓存相关的更改,并专注于侦听这些更改(通过服务工作者生命周期事件或 postMessage()
通信)。
我正在尝试在我的离线工作应用程序中将 appcache 更改为 serviceworker。我已从 html 页面删除清单标签并创建 serviceworker.js 作为生命周期事件。但是,appcache 事件的使用如下所示:
function framework(){
this.appCache = window.applicationCache;
//more other codes
}
var fw = new framework();
现在,生命周期事件是这样检查的:
if (fw.appCache) {
/* Checking for an update. Always the first event fired in the sequence.*/ fw.appCache.addEventListener('checking', handleCacheEvent, false);
/* An update was found. The browser is fetching resources.*/ fw.appCache.addEventListener('downloading', handleCacheEvent, false);
/* Fired if the manifest file returns a 404 or 410.
This results in the application cache being deleted. */ fw.appCache.addEventListener('obsolete', handleCacheEvent, false);
/* The manifest returns 404 or 410, the download failed,
or the manifest changed while the download was in progress.*/ fw.appCache.addEventListener('error', handleCacheError, false);
/* Fired for each resource listed in the manifest as it is being fetched.*/fw.appCache.addEventListener('progress', handleProgressEvent, false);
/*Fired after the first cache of the manifest. */ fw.appCache.addEventListener('cached', function(event){handleCacheEvent(event);removeProcessing();$("#processingTextId").html("");}, false);
/* Fired after the first download of the manifest.*/ fw.appCache.addEventListener('noupdate', function(event){handleCacheEvent(event);removeProcessing(); $("#processingTextId").html("");}, false);
/* Fired when the manifest resources have been newly redownloaded. */ fw.appCache.addEventListener('updateready', function(e) {if (fw.appCache.status == fw.appCache.UPDATEREADY) {alert('Successful'); try{fw.appCache.swapCache();window.location.reload();} catch(err){}}}, false);
}
function handleCacheEvent(event) {$("#processingTextId").html(event.type);}
function handleProgressEvent(event) {$("#processingTextId").html("(" + event.loaded + " of "+ event.total +")");}
function handleCacheError(event) {$("#processingTextId").html("Cache failed to update!")
所以,我的问题是如何用服务工作者事件替换此事件。我的 serviceworker 已注册并正确缓存资产。现在,我在 index.html
中这样做注册
<script type="text/javascript">
if('serviceWorker' in navigator){
navigator.serviceWorker.register('serviceworker.js')
.then(registration =>{
console.log('registration successful:',registration.scope);
})
.catch(err=>{
console.log('registration failed:',err);
});
}
</script>
我创建了单独的 serviceworker.js。
如何用serviceworker替换那些appcache事件?
在使用 Service Worker 时,您不会自动结束这些事件中的任何一个。此外,service worker 填充和更新缓存的模型 "open ended" 比 AppCache 多得多,因此将 service worker 缓存转换为等效的 AppCache 事件并不总是可能的。
不过,总的来说,有两件事可以提供帮助:
阅读 Service Worker Lifecycle. Some events that you might care about could be approximated by listening for equivalent changes to the service worker lifecycle. For instance, if you precache some URLs during service worker installation,然后新注册的服务工作者离开 installing
状态大致相当于 AppCache 清单完成缓存时的状态。类似地,如果您检测到先前注册的 service worker 何时有更新(并且该更新是由于要预缓存的 URL 列表发生更改),那么这大致对应于更新 AppCache 清单的时间。
如果您的服务人员使用 "runtime" 缓存,其中 URL 被添加到 fetch
处理程序内部的缓存中,您可以使用以下技术告诉您的客户端页面什么时候已缓存新项目,使用 postMessage()
进行通信。
您服务人员的一部分 JavaScript:
const cacheAddAndNotify = async (cacheName, url) => {
const cache = await caches.open(cacheName);
await cache.add(url);
const clients = await self.clients.matchAll();
for (const client of clients) {
client.postMessage({cacheName, url});
}
};
self.addEventListener('fetch', (event) => {
// Use cacheAddAndNotify() to add to your cache and notify all clients.
});
您网络应用程序的一部分 JavaScript:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.addEventListener('message', (event) => {
const {cacheName, url} = event.data;
// cacheName and url represent the entry that was just cached.
});
}
同样,您所听内容的具体细节以及您对此的反应方式实际上将取决于您在服务工作者中的逻辑。不要指望所有事件之间都有 1:1 映射。相反,将此迁移作为一个机会来思考您真正关心的与缓存相关的更改,并专注于侦听这些更改(通过服务工作者生命周期事件或 postMessage()
通信)。