之前做好的WebApp在Python Flask沒有運作時候首先會進入Loading畫面等待10秒圈圈旋轉了10次后進入全屏幕白色:
離綫時候爲了依靠Service Worker將Web Shell緩存,所以要在index.html注冊service-worker.js
// CODELAB: Register service worker.
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js')
.then((reg) => {
console.log('Service worker registered.', reg);
});
});
}
而且要在service-worker.js寫明需要緩存的檔案,意思是說安裝之後就從打開static-v1緩存加入offline.html:
self.addEventListener('install', (evt) => {
console.log('[ServiceWorker] Install');
// CODELAB: Precache static resources here.
evt.waitUntil(
caches.open('static-cache-v1').then((cache) => {
console.log('[ServiceWorker] Pre-caching offline page');
return cache.addAll(['/offline.html']);
})
);
self.skipWaiting();
});
真正運行到addAll()時候,瀏覽器會在install安裝時候向服務器發送所有request,如果其中任何一個或以上的request失敗,那麽整個安裝將會失敗,因此整個流程可以保證安裝完畢之後的WebApp已經完整地緩存了一次。
這時候如果你遇到找不到luxon-1.11.4.js.map,那麽在Chrome的DevTool settings裏面,需要取消"Enable JavaScript source maps"以及"Enable CSS source maps"。
這時候如果看見http://127.0.0.1/service-worker.js下載出現錯誤,可能要加上favicon.ico。
這時候如果看見service-worker不能啓動,那麽需要確保service-worker.js的mime-type是application/javascript,而使用Flask要這樣寫send_from_directory("templates", “service-worker.js”, mimetype="application/javascript")。
這時候確保service worker activated and is running:
Service除了install之外,也可以增加activate listener,在activate的時候,如果當前cache的名稱與新的CACHE_NAME名稱不一樣,那麽就將當前的cache從caches移除: caches.delete(key)
// CODELAB: Remove previous cached data from disk.
evt.waitUntil(
caches.keys().then((keyList) => {
return Promise.all(keyList.map((key) => {
if (key !== CACHE_NAME) {
console.log('[ServiceWorker] Removing old cache', key, 'new cache', CACHE_NAME);
return caches.delete(key);
}
}));
})
);
這時候將CACHE_NAME從v1改爲v2重啓網頁服務器的話,會見到綠燈的Status #改變,并且看見以下console messages:
在寫好install及activate之後,最後要寫好fetch能夠讓cache真正工作,這裏大概意思是,請求模式如非轉頁的話就不需要緩存了;如果是轉頁的話就從網絡fetch進來,fetch有exception時候就catch出來處理,處理方法是無論請求什麽頁面也好,統一打開緩存指明的offline.html檔案,而offline.html可以是一個道歉畫面,或者是一個離綫小游戲,或者是一個離綫頁面:
// CODELAB: Add fetch event handler here.
if (evt.request.mode !== 'navigate') {
// Not a page navigation, bail.
return;
}
evt.respondWith(
fetch(evt.request)
.catch(() => {
return caches.open(CACHE_NAME)
.then((cache) => {
return cache.match('offline.html');
});
})
);
現在無論使用本機Chrome或者Firefox都可以在沒有Flask運行情況下見到offline.html
sa
End