ServiceWorker で、ネットワークから取得しようして失敗したらキャッシュにフォールバックするやつ
ここ最近、ServiceWorker を使って色々試しているのだけど、その中のひとつ。
以下の内容を、エントリーの HTML や参照系の API に適用して、アプリケーションのオフライン対応を実現する。通常はネットワークから取得した最新の内容を使うが、オフラインやネットワークが不安定な場合はキャッシュの内容を使う。
- ネットワークから取得しようとして失敗したらキャッシュを使う
- ネットワークから取得するとき、1秒のタイムアウトを設定する
- ネットワークから取得しようとして成功したらキャッシュに保存する
- ネットワークから取得しようとして失敗した場合、キャッシュが存在しなかった場合はログにその旨を出力する
ServiceWorker 内で使える API は Promise を返すものがほとんどなので、Promise を駆使するかんじ。
var CACHE_NAME = 'v1'; var fetchWithTimeout = function(request) { return new Promise(function(resolve, reject) { setTimeout(reject, 1000); return fetch(request).then(resolve); }); }; self.addEventListener('fetch', function(event) { // 本当はここでパスやヘッダーの内容を見て、キャッシュすべき対象か調べる event.respondWith( fetchWithTimeout(event.request) .then(function(response) { return caches.open(CACHE_NAME).then(function(cache) { console.log('Put to cache', response); cache.put(event.request, response.clone()); return response; }); }) .catch(function(e) { console.error('Failed to fetch', e); return caches.open(CACHE_NAME).then(function(cache) { console.log('Fallback to cache', event.request); var response = cache.match(event.request); if (!response) { console.error('Missing cache', event.request); return; } return response; }); }) ); });