資源請求的攔截代理:html
一、資源請求的判斷:正則表達式
(1)fetch 事件會攔截頁面上全部的網絡資源請求,但咱們一般只對部分資源請求進行處理,數據庫
其他的請求會繼續走瀏覽器默認的資源請求流程瀏覽器
(2)fetch 事件回調參數的 event.request 屬性描述了當前被攔截的資源請求,能夠經過它來進行判斷分類。緩存
event.request 是 Request 對象的實例,包含了資源請求的 URL、請求模式、請求頭等所有信息網絡
(3)通常狀況下,資源請求的判斷能夠經過對 event.request.url 進行匹配來實現異步
// 全等匹配 if (event.request.url === 'http://127.0.0.1:8080/data.txt') { // 匹配成功 } // 正則匹配 if (/\/data\.txt/.test(event.request.url)) { // 匹配成功 } // 藉助 URL 進行匹配 let url = new URL(event.request.url) if ( url.hostname === '127.0.0.1' && url.port === '8080' && url.pathname === '/data.txt' ) { // 匹配成功 }
注:正則表達式可參考我以前的隨筆 http://www.javashuo.com/article/p-vxoolmlm-cm.html性能
二、資源請求的響應:fetch
(1)fetch 事件回調參數的方法 event.respondWith(r) 能夠指定資源請求的響應結果url
(2)respondWith(r) 方法的參數 r 能夠是一個 Response 對象實例,也能夠是一個 Promise 對象,這個 Promise 對象
在異步執行完成的時候一樣須要 resolve 返回一個 Response 對象實例做爲請求的響應結果
// 直接返回 Response 對象 event.respondWith(new Response('Hello World!')) // 等待 1 秒鐘以後異步返回 Response 對象 event.respondWith(new Promise(resolve => { setTimeout(() => { resolve(new Response('Hello World!')) }, 1000) }))
三、異步資源請求響應:
(1)event.respondWith 方法與 install、activate 事件回調參數中的 event.waitUntil 相似,
起到了擴展延長 fetch 事件生命週期的做用
(2)在 fetch 事件回調同步執行完畢以前若是沒有調用 event.respondWith(r) 指定資源響應結果,
那麼就會進入瀏覽器默認的資源請求流程當中
// 錯誤用法 self.addEventListener('fetch', event => { if (event.request.url === 'http://127.0.0.1:8080/data.txt') { setTimeout(() => { event.respondWith(new Response('Hello World!')) }, 1000) } }) // 正確用法 // 等待 1 秒鐘以後異步返回 Response 對象 event.respondWith(new Promise(resolve => { setTimeout(() => { resolve(new Response('Hello World!')) }, 1000) }))
四、資源請求響應的錯誤處理:
(1)當使用了 event.respondWith 指定資源響應以後,不管是以同步仍是異步的方式,最終都須要返回 Response 對象
(2)在調用 event.respondWith 的時候,須要主動捕獲並處理錯誤、異常返回結果
五、資源請求與響應操做的管理:
在 fetch 事件回調當中主要進行着資源請求匹配和響應結果返回的操做,能夠把這個過程當作一個路由分發的問題,
所以咱們能夠封裝一個 Router 類來實現對路由的匹配規則和操做分發的統一管理
本地存儲管理:
一、由於基於性能上的考慮,Service Worker 在設計標準時就要求了任何耗時操做必須異步實現。這也致使了在
Service Worker 做用域下可以使,目前只有 Cache API 和 IndexedDB,由於目前只有兩者在功能實現上所有
採用了異步形式,而其餘諸如 localStorage 屬於同步方法,所以沒法在 Service Worker 中使用
二、Cache API 與 IndexedDB 的應用場景:
(1)Cache API 適用於請求響應的本地存儲:爲資源請求與響應的存儲量身定作的,它採用了鍵值對的數據模型
存儲格式,以請求對象爲鍵、響應對象爲值,正好對應了發起網絡資源請求時請求與響應一一對應的關係
(2)IndexedDB 是一種非關係型數據庫,它的存儲對象主要是數據,好比數字、字符串、Plain Objects、Array 等,
以及少許特殊對象好比 Date、RegExp 等等,對於 Request、Response 這些是沒法直接被 IndexedDB 存儲的
(3)Cache API 和 IndexedDB 在功能上是互補的。在設計本地資源緩存方案時一般以 Cache API 爲主,
但在一些複雜的場景下,Cache API 這種請求與響應一一對應的形式存在着侷限性,所以須要結合上功能上更爲
靈活的 IndexedDB,經過 IndexedDB 存取一些關鍵的數據信息,輔助 Cache API 進行資源管理
三、緩存注意項:
(1)本地存儲空間是有限的:瀏覽器提供了 StorageEstimate API 去查詢當前緩存空間的使用狀況
navigator.storage.estimate() .then(estimate => { // 設備爲當前域名所分配的存儲空間總大小 console.log(estimate.quota) // 當前域名已經使用的存儲空間大小 console.log(estimate.usage) })
(2)資源的存取過程可能會失敗:應該隨時作好存取失敗時的異常捕獲與降級方案,確保程序運行時不會出錯
(3)存儲的資源可能會過時:要及時作好資源的更新和舊資源的清理工做