我已经在Web应用程序中实现了service worker,并试图缓存所有html,css,js和images文件。我的托管服务是firebase,在成功部署后,我测试了该服务是否可以正常工作以及文件是否将被缓存,不幸的是会发生以下错误。
service-worker.js
let cacheName = 'my-tools-v1';
let filesToCache = [
'/',
'/css/app.css',
'/css/diffview.css',
'/css/json-lint.css',
'/css/materialize.css',
'/images/favicon.png',
'/images/icons/apple-touch-icon.png',
'/images/icons/apple-touch-icon-57x57.png',
'/images/icons/apple-touch-icon-72x72.png',
'/images/icons/apple-touch-icon-76x76.png',
'/images/icons/apple-touch-icon-114x114.png',
'/images/icons/apple-touch-icon-120x120.png',
'/images/icons/apple-touch-icon-144x144.png',
'/images/icons/apple-touch-icon-152x152.png',
'/images/icons/apple-touch-icon-180x180.png',
'/images/icons/icon-72x72.png',
'/images/icons/icon-96x96.png',
'/images/icons/icon-128x128.png',
'/images/icons/icon-144x144.png',
'/images/icons/icon-152x152.png',
'/images/icons/icon-192x192.png',
'/images/icons/icon-384x384.png',
'/images/icons/icon-512x512.png',
'/js/index.js',
'/js/css-lint.js',
'/js/difflib.js',
'/js/diffview.js',
'/js/ipsum-generator.js',
'/js/json2.js',
'/js/json-lint.js',
'/js/jsonlint.js',
'/js/lorem-ipsum.js',
'/js/materialize.js',
'/js/visual-difference.js',
'/bower_components/codemirror/lib/codemirror.js',
'/bower_components/codemirror/mode/javascript/javascript.js',
'/bower_components/codemirror/mode/css/css.js',
'/bower_components/codemirror/addon/edit/matchbrackets.js',
'/bower_components/codemirror/addon/comment/continuecomment.js',
'/bower_components/codemirror/addon/comment/comment.js',
'/bower_components/ft-csslint/dist/csslint.js',
'/bower_components/jquery/dist/jquery.slim.min.js',
'/bower_components/kanye-ipsum/dist/jquery.kanye-ipsum.min.js',
'/bower_components/codemirror/lib/codemirror.css',
'/index.html',
'/css-lint.html',
'/ipsum-generator.html',
'/json-lint.html',
'/visual-difference.html',
'/notfound.html',
'/404.html'
];
self.addEventListener('install', (e) => {
console.log('[ServiceWorker] Install');
e.waitUntil(
caches.open(cacheName).then((cache) => {
console.log('[ServiceWorker] Caching app shell');
return cache.addAll(filesToCache);
})
);
});
self.addEventListener('activate', (e) => {
console.log('[ServiceWorker] Activate');
e.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map((key) => {
if (key !== cacheName) {
console.log('[ServiceWorker] Removing old cache', key);
return caches.delete(key);
}
}));
})
);
});
self.addEventListener('fetch', (e) => {
console.log('[ServiceWorker] Fetch', e.request.url);
e.respondWith(
caches.match(e.request).then((response) => {
return response || fetch(e.request);
})
);
});
然后,因此没有缓存所有文件。但是,如果我删除404.html或将其重命名为其他名称,则服务工作程序将正常运行,并且将缓存所有文件。同样奇怪的是,在我的本地服务器中,服务工作者可以工作并缓存404.html,但是在firebase中失败。
为什么404.html在服务工作者缓存期间导致未捕获的错误?我该如何解决?
答案 0 :(得分:0)
Cache.addAll()
是全有或全无的API。如果任何响应不在200 HTTP状态代码范围内,则不会缓存任何内容。
如果任何资源无法缓存,cache.addAll将拒绝。这意味着仅当cache.addAll中的所有资源都已被缓存时,服务工作者才会安装。
Firebase为404 Not Found
文件返回/404.html
。
解决此问题的一种方法是像您一样拥有文件/notfound.html
,然后在需要时将其返回到fetch
中。
答案 1 :(得分:0)
如果404错误html页面返回404
https状态(应如此),则无法将404错误html页面添加到缓存中。
但是,即使网站处于脱机模式,您仍然可以使用Service Worker创建404错误页面并将其用于不在缓存中的网站。
在catch()
请求之后使用fetch()
并创建全新的响应
简约示例:
// self is ServiceWorkerGlobalScope
self.addEventListener( 'fetch', function ( /** @type {FetchEvent} */ event )
{
//const caches = ( event.target.caches );
event.respondWith(
caches.match( event.request ).then( ( /** @type {Response | undefined} */ response ) =>
{
if ( response ) {
return response;
}
return fetch( event.request.clone() ).then( ( /** @type {Response} */ response ) =>
{
//…
return response;
}
).catch( () =>
{
return new Response( '<h1>404 - Not found</h1><p>more HTML here …</p>', {
status: 404,
statusText: 'Not found',
headers: new Headers( {
'Content-Type': 'text/html'
} )
} );
} );
}
)
);
} );