配飯短文:離線Web應用入門

前言

最近筆者有些精神恍惚,人生中一些印象深入的事情,像PPT同樣從腦海中一一閃過,好比:javascript

  • 小學時候做爲勞動委員,常年負責掏學校裏一個蘑菇形的垃圾桶,結果有一天撿到了好幾張一塊錢,賊開心。
  • 大學裏有一天下晚自習,一推門,瞧見一個天使般面容的女子,賊開心。
  • 有一次通宵加班(非快狗打車),早上回家時,反向地鐵竟然有座位,賊開心。
  • 有一次被提了一個bug:
    image

(事實證實文字順序並不影響閱讀)做爲一個被困在Webview裏的FE,我沉默了,賊不開心。css

----------以上是暖場----------html

無網絡時,前端真的什麼都作不了嗎?本文滾動條以及直覺告訴你,那必定不是的。
聯想到幾個月前寫的一篇無人問津的文章:《Service Worker從入門到出門》(這是廣告,方便的話請去點贊,對您沒什麼好處,但我會高興),筆者意識到,若是不計代價的話,藉助Service Worker,那個bug裏要求的效果,其實也不是不可能實現。前端

本文決定,不糾結於那個bug,而針對無網絡的極限場景,用盡可能少的代碼,實現一個demo級別的離線Web應用。java

一點說明

所謂的離線應用,不是指一直離線,一直沒網的話,那還玩些什麼呢?而是指一開始用戶是有網絡的,可是用戶由於走進地鐵,或者買了近兩年的iPhone,忽然就沒網了,此時,讓頁面展現一些緩存的內容。瀏覽器

理清思路、抓住關鍵

實現一個離線Web應用的關鍵在於:攔截請求緩存資源緩存

在此假設讀者瞭解Service WorkerCacheStorage的基礎。服務器

簡單來說,若是不考慮HTTP緩存的話,一個普通Web App獲取靜態資源是從服務器獲取的。可是Service Worker至關於在瀏覽器的出口加了一層代理,有着攔截並處理請求的能力,這使得咱們有機會選擇資源是從服務器取仍是從CacheStorage中取。
CacheStorage既然做爲一種緩存,那大概就要聽從「若是命中緩存則返回緩存中的資源,不然從遠處取」的基本策略。
具體到一個Web應用,靜態資源能夠粗略分爲html和其它(js、css、圖片等),html做爲應用入口,有着它的特殊性。實現離線應用的關鍵在於緩存入口html,這是實現離線應用的核心思路。設想一下,若是html保存在本地,那在無網絡的狀況下,瀏覽器也是能夠打開的,至於html引用的其它靜態資源,若是緩存過,那也是能夠訪問的。網絡

代碼

首先,初始化一個項目,在此以Vue項目爲例,在入口html中註冊service worker:post

<script> if ('serviceWorker' in navigator) { window.addEventListener('load', function () { navigator.serviceWorker.register('/demo/service-worker.js').then(function (reg) { console.log('service-worker.js註冊成功'); }, function (err) { console.log('service-worker.js註冊失敗'); }); }); } </script>
複製代碼

service-worker.js代碼:

// 每次更新須要更新版本號
const cacheVersion = 'v1';

// service worker激活時的初始化操做,非關鍵代碼,能夠不看
self.addEventListener('activate', function (event) {
    event.waitUntil(
        caches.keys().then(function (cacheNames) {
            return Promise.all(
                cacheNames.map(function (cacheName) {
                    // 若是當前版本和緩存版本不一致,則刪除其它版本的cache
                    if (cacheName !== cacheVersion) {
                        return caches.delete(cacheName);
                    }
                })
            );
        })
    );
});

// 核心代碼,最好看一看
self.addEventListener('fetch', function (event) {
    event.respondWith(
        caches.match(event.request)
            .then(function (response) {
                // 如匹配了cache,則直接返回cache中的資源
                // 不然fetch資源並緩存下來
                return response || fetch(event.request).then(function (r) {
                    caches.open(cacheVersion).then(function (cache) {
                        cache.put(event.request, r);
                    });
                    return r.clone();
                });
            })
    );
});
複製代碼

成果展現

代碼部署好後,訪問頁面,刷新,能夠看到:cacheStorage中的靜態資源已經緩存成功:

image
而後咱們斷網,刷新,能夠發現:頁面仍是能夠訪問的,靜態資源的響應狀態碼是200,但標註了 (from ServiceWorker)
image

總結

因此,如此少的代碼,就能夠實現一個離線Web應用,可是從Demo到實際應用,還有好長的路要走。不管如何,本文所述的是離線Web應用的基本思路和方法。但願你們可以喜歡,甚至點贊。(舒適提示:點贊並不花錢)

image

關於咱們

快狗打車前端團隊專一前端技術分享,按期推送高質量文章,歡迎關注點贊。 文章同步發佈在公衆號喲,想要第一時間獲得最新的資訊,just scan it !

公衆號二維碼
相關文章
相關標籤/搜索