Rails PWA 中的 CacheStorage 始终为空。在 service-worker.js cache.addAll 似乎没有缓存任何东西
CacheStorage in Rails PWA always empty. In service-worker.js cache.addAll doesn't seem to cache anything
在寻找某种解决方案几天后,我一无所获。我的 service-worker 注册、安装和激活没有问题,但 cache.addAll 似乎无声地失败了。
我正在使用控制器为 service-worker 服务,manifest.json 作为 erb 视图。我只使用 webpacker 而不是资产管道,这排除了用于此类事情的一些常见宝石。
这是我的服务-worker.js.erb:
const expectedCaches = ['static-v2'];
function onInstall(event) {
console.log('[Serviceworker]', "Installing!", event);
event.waitUntil(
caches.open("static-v2")
.then(function(cache) {
return cache.addAll([
'/offline.html',
'<%= asset_pack_path 'application.js' %>',
'<%= asset_pack_path 'media/images/Convertable.png' %>',
'<%= root_path %>',
])
.then(function(e){
console.log(e);
})
.catch(function(e){
console.log(e.message);
});
}).catch(function(err){
console.log(err.message);
})
);
}
function onActivate(event) {
console.log('[Serviceworker]', "Activating!", event);
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.filter(function(cacheName) {
// Return true if you want to remove this cache,
// but remember that caches are shared across
// the whole origin
return expectedCaches.includes(cacheName);
}).map(function(cacheName) {
return caches.delete(cacheName);
})
);
})
);
}
function onFetch(event) {
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'))) {
console.log('[Serviceworker]', "Fetching offline content", event);
return caches.match('/offline.html');
}
})
})
);
}
self.addEventListener('install', onInstall);
self.addEventListener('activate', onActivate);
self.addEventListener('fetch', onFetch);
还有我的manifest.json.erb
{
"short_name": "My APP",
"name": "My APP for Everyone!",
"icons": [
{
"src": "<%= asset_pack_path 'media/images/Convertable.png' %>",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "<%= asset_pack_path 'media/images/Convertable.png' %>",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": "<%= root_path %>",
"background_color": "#fff",
"display": "standalone",
"scope": "<%= root_path %>",
"theme_color": "#000"
}
就像我说的,它注册和安装都很好,但是当我使用 chrome 开发工具进入离线模式时,它无法加载任何应该被缓存的东西,我在控制台中得到了这个:
The FetchEvent for "http://localhost:3000/offline.html" resulted in a network error response: an object that was not a Response was passed to respondWith().
Promise.then (async)
onFetch @ service-worker.js:47
这是因为未在缓存中找到任何内容,因此返回未定义作为响应。调试 fetch 事件处理程序,我发现 CacheStorage 对象确实是空的。查看 chrome 开发工具的应用程序选项卡我找不到任何缓存,尽管我不太确定它最终应该在哪个缓存中(列出了几个)。
我在 Firefox 中也得到了同样的结果。我希望我错过了一些简单的事情,有人可以向我指出,或者至少有人可以让我走上正确的道路。我会尽力响应任何要求提供额外信息的请求。
谢谢!
看起来在 onActivate
事件处理程序中,您正在从缓存存储中删除您之前在 onInstall
事件中添加的项目。
您应该删除不在 expectedCaches
数组中的缓存(现在您正在做相反的事情:-))。所以尝试将条件更改为return !expectedCaches.includes(cacheName);
(添加感叹号),这将只过滤旧缓存。
在寻找某种解决方案几天后,我一无所获。我的 service-worker 注册、安装和激活没有问题,但 cache.addAll 似乎无声地失败了。
我正在使用控制器为 service-worker 服务,manifest.json 作为 erb 视图。我只使用 webpacker 而不是资产管道,这排除了用于此类事情的一些常见宝石。
这是我的服务-worker.js.erb:
const expectedCaches = ['static-v2'];
function onInstall(event) {
console.log('[Serviceworker]', "Installing!", event);
event.waitUntil(
caches.open("static-v2")
.then(function(cache) {
return cache.addAll([
'/offline.html',
'<%= asset_pack_path 'application.js' %>',
'<%= asset_pack_path 'media/images/Convertable.png' %>',
'<%= root_path %>',
])
.then(function(e){
console.log(e);
})
.catch(function(e){
console.log(e.message);
});
}).catch(function(err){
console.log(err.message);
})
);
}
function onActivate(event) {
console.log('[Serviceworker]', "Activating!", event);
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.filter(function(cacheName) {
// Return true if you want to remove this cache,
// but remember that caches are shared across
// the whole origin
return expectedCaches.includes(cacheName);
}).map(function(cacheName) {
return caches.delete(cacheName);
})
);
})
);
}
function onFetch(event) {
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'))) {
console.log('[Serviceworker]', "Fetching offline content", event);
return caches.match('/offline.html');
}
})
})
);
}
self.addEventListener('install', onInstall);
self.addEventListener('activate', onActivate);
self.addEventListener('fetch', onFetch);
还有我的manifest.json.erb
{
"short_name": "My APP",
"name": "My APP for Everyone!",
"icons": [
{
"src": "<%= asset_pack_path 'media/images/Convertable.png' %>",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "<%= asset_pack_path 'media/images/Convertable.png' %>",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": "<%= root_path %>",
"background_color": "#fff",
"display": "standalone",
"scope": "<%= root_path %>",
"theme_color": "#000"
}
就像我说的,它注册和安装都很好,但是当我使用 chrome 开发工具进入离线模式时,它无法加载任何应该被缓存的东西,我在控制台中得到了这个:
The FetchEvent for "http://localhost:3000/offline.html" resulted in a network error response: an object that was not a Response was passed to respondWith().
Promise.then (async)
onFetch @ service-worker.js:47
这是因为未在缓存中找到任何内容,因此返回未定义作为响应。调试 fetch 事件处理程序,我发现 CacheStorage 对象确实是空的。查看 chrome 开发工具的应用程序选项卡我找不到任何缓存,尽管我不太确定它最终应该在哪个缓存中(列出了几个)。
我在 Firefox 中也得到了同样的结果。我希望我错过了一些简单的事情,有人可以向我指出,或者至少有人可以让我走上正确的道路。我会尽力响应任何要求提供额外信息的请求。
谢谢!
看起来在 onActivate
事件处理程序中,您正在从缓存存储中删除您之前在 onInstall
事件中添加的项目。
您应该删除不在 expectedCaches
数组中的缓存(现在您正在做相反的事情:-))。所以尝试将条件更改为return !expectedCaches.includes(cacheName);
(添加感叹号),这将只过滤旧缓存。