摘要:需要提前掌握的基本使用檢測是否存在,創建緩存總對象。之后更新后的啟動并觸發事件。此時,當前頁面生效的依然是老版本的,新的會進入狀態。當頁面關閉之后,老的會被干掉,新的接管頁面一旦新的生效后會觸發事件。
前言: 看到一篇講解service worker的文章, 基礎講的還不錯, 所以轉了以后作為自己的參考
Service Worker是什么service worker 是獨立于當前頁面的一段運行在瀏覽器后臺進程里的腳本。它的特性將包括推送消息,背景后臺同步, geofencing(地理圍欄定位),攔截和處理網絡請求。
這個 API 會讓人興奮的原因是,它可以使你的應用先訪問本地緩存資源,所以在離線狀態時,在沒有通過網絡接收到更多的數據前,仍可以提供基本的功能(一般稱之為 Offline First)。
在 service worker 之前,另一個叫做 APP Cache 的 api 也可以提供離線體驗。APP Cache 的的主要問題是坑比較多,而且其被設計為只適合于單頁 web 應用程序,對于傳統的多頁網站則不適合。service worker 的設計規避了這些痛點。
關于 service worker 的一些注意點:
service worker 是一個JavaScript worker ,所以它不能直接訪問 DOM 。但 service worker 可以通過postMessage 接口與跟其相關的頁面進行通信,發送消息,從而讓這些頁面在有需要的時候去操縱 DOM 。
Service worker 是一個可編程的網絡代理,允許你去控制如何處理頁面的網絡請求, 可以處理fetch請求。
Service worker 在不使用時將被終止,并會在需要的時候重新啟動,因此你不能把onfetch 和onmessage事件來作為全局依賴處理程序。如果你需要持久話一些信息并在重新啟動Service worker后使用他,可以使用 IndexedDBAPI ,service worker 支持。
Service Worker 的緩存機制是依賴 Cache API 實現的 Service worker 廣泛使用了 promise。
Service worker依賴 HTML5 fetch API
Service Workers 要求必須在 HTTPS 下才能運行
Service Worker生命周期注冊service worker,在網頁上生效
安裝成功,激活 或者 安裝失敗(下次加載會嘗試重新安裝)
激活后,在sw的作用域下作用所有的頁面,首次控制sw不會生效,下次加載頁面才會生效。
sw作用頁面后,處理fetch(網絡請求)和message(頁面消息)事件 或者 被終止(節省內存)。
需要提前掌握的APICache API基本使用
(1)檢測api是否存在
if("caches" in window) { // Has support! }
(2)caches.open,創建緩存總對象。如下創建名為 test-cache 的緩存。
caches.open("test-cache").then(function(cache) { // Cache is created and accessible });
(3)cache.add和cache.addAll,添加緩存內容。其中cache.add只添加一個,cache.addAll可以添加多個。
caches.open("test-cache").then(function(cache) { cache.addAll(["/", "/images/logo.png"]) .then(function() { // Cached! // or use cache.add cache.add("/page/1"); // "/page/1" URL will be fetched and cached! }); });
(4)cache.keys(),查看已經緩存的數據
caches.open("test-cache").then(function(cache) { cache.keys().then(function(cachedRequests) { console.log(cachedRequests); // [Request, Request] }); });
(5)cache.match和cache.matchAll,匹配緩存文件路徑
caches.open("test-cache").then(function(cache) { cache.match("/page/1").then(function(matchedResponse) { console.log(matchedResponse); }); });
(6)cache.delete,刪除緩存。
caches.open("test-cache").then(function(cache) { cache.delete("/page/1"); });
Fetch API基本使用
// url (required), options (optional) fetch("https://davidwalsh.name/some/url", { method: "get" }).then(function(response) { }).catch(function(err) { // Error :( });
其中options對象包含以下屬性:
method - GET, POST, PUT, DELETE, HEAD
url - 請求的鏈接
headers - 請求的header對象
referrer - 請求的referrer對象
mode - cors, no-cors, same-origin
credentials - 設置請求可不可以攜帶cookie
redirect - follow, error, manual
integrity - 子資源完整值
cache - 緩存模式 (default, reload, no-cache)
可以在fetch中傳入Request對象實例:
var request = new Request("https://davidwalsh.name/users.json", { method: "POST", mode: "cors", redirect: "follow", headers: new Headers({ "Content-Type": "text/plain" }) }); // Now use it! fetch(request).then(function() { /* handle response */ });
可以自定義返回的Response對象實例,其中的options有:
type - basic, cors
url
useFinalURL - 上面的url參數是不是最終的URL
status - 狀態碼(ex: 200, 404, etc.)
ok - 是否成功響應 (范圍在 200-299)
statusText - 狀態碼 (ex: OK)
headers - 響應的headers對象
另外Response的實例還具備以下方法:
clone() - 創建Response對象的克隆。
error() - 返回與網絡錯誤關聯的新Response對象。
redirect() - 使用不同的URL創建新響應。
arrayBuffer() - 返回使用ArrayBuffer解析的promise。
blob() - 返回使用Blob解析的promise。
formData() - 返回使用FormData對象解析的promise。
json() - 返回使用JSON對象解析的promise。
text() - 返回使用USVString(文本)解析的promise。
// Create your own response for service worker testing // new Response(BODY, OPTIONS) var response = new Response(".....", { ok: false, status: 404, url: "/" }); // The fetch"s `then` gets a Response instance back fetch("https://davidwalsh.name/") .then(function(responseObj) { console.log("status: ", responseObj.status); });Service Worker的使用
兼容低版本,注入Cache API的一個polyfill,Service Worker需要依賴Cache API:
self.importScripts("./serviceworker-cache-polyfill.js");
注冊service worker:
if ("serviceWorker" in navigator) { navigator.serviceWorker.register("/sw.js").then(function(registration) { // Registration was successful console.log("ServiceWorker registration successful with scope: ", registration.scope); }).catch(function(err) { // registration failed :( console.log("ServiceWorker registration failed: ", err); }); }
上面的代碼檢查 service worker API 是否可用,如果可用, /sw.js 這個文件將會作為 service worker 被注冊。
如果這個 service worker 已經被注冊過,瀏覽器會自動忽略上面的代碼。
有一個特別要注意是 service worker 文件的路徑。你一定注意到,在這個例子中,service worker 文件被放在這個域的根目錄下,這意味著 service worker是跟網站同源的。換句話說,這個 service worker 將會獲取到這個域下的所有 fetch 事件。如果 service worker文件注冊到/example/sw.js ,那么 service worker 只能收到 /example/ 路徑下的 fetch 事件(比如: /example/page1/, /example/page2/)。
安裝service worker:
var CACHE_NAME = "my-site-cache-v1"; var urlsToCache = [ "/", "/styles/main.css", "/script/main.js" ]; self.addEventListener("install", function(event) { // Perform install steps event.waitUntil( caches.open(CACHE_NAME) .then(function(cache) { console.log("Opened cache"); return cache.addAll(urlsToCache); }) ); });
上面代碼聲明了需要緩存的內容,如果所有的文件都緩存成功,service worker 就安裝成功了。如果任何一個文件下載失敗,那么安裝步驟就會失敗。這個方式依賴于你自己指定的資源,但這意味著,你需要非常仔細地確定哪些文件需要被緩存。指定了太多文件的話,會增加失敗率。
對緩存跟返回請求的處理
self.addEventListener("fetch", function(event) { event.respondWith( caches.match(event.request) .then(function(response) { // Cache hit - return response if (response) { return response; } // IMPORTANT: Clone the request. A request is a stream and // can only be consumed once. Since we are consuming this // once by cache and once by the browser for fetch, we need // to clone the response var fetchRequest = event.request.clone(); return fetch(fetchRequest).then( function(response) { // Check if we received a valid response if(!response || response.status !== 200 || response.type !== "basic") { return response; } // IMPORTANT: Clone the response. A response is a stream // and because we want the browser to consume the response // as well as the cache consuming the response, we need // to clone it so we have 2 stream. var responseToCache = response.clone(); caches.open(CACHE_NAME) .then(function(cache) { cache.put(event.request, responseToCache); }); return response; } ); }) );
如果我們想在緩存中添加新的請求緩存,可以通過處理fetch請求的response,將其添加到緩存中即可。代碼里我們做了以下事情:
添加一個 callback 到 fetch 請求的 .then 方法中。 一旦我們獲得一個 response,我們進行如下的檢查:
1. 確保 response 有效
2. 檢查 response 的狀態是200
3. 確保 response 的類型是 basic 類型的,這說明請求是同源的,這意味著第三方的請求不能被緩存。
如果檢查通過會clone 這個請求。這么做的原因是如果 response 是一個 Stream,那么它的 body 只能被消費一次。所以為了讓瀏覽器跟緩存都使用這個body,我們必須克隆這個 body,一份到瀏覽器,一份到緩存中緩存。
重新激活你的 service worker 總會有要更新的時候。在那時,你需要按照以下步驟來更新:
更新你 service worker 的 JavaScript 文件 當用戶瀏覽你的網站時,瀏覽器嘗試在后臺重新下載 service worker 的腳本文件。經過對比,只要服務器上的文件和本地文件有一個字節不同,這個文件就認為是新的。
之后更新后的 service worker 啟動并觸發 install 事件。此時,當前頁面生效的依然是老版本的 service worker,新的 service worker 會進入 “waiting” 狀態。
當頁面關閉之后,老的 service worker 會被干掉,新的 servicer worker 接管頁面 一旦新的 service worker 生效后會觸發 activate 事件。 通常來講,需要在 activate 的 callback 中進行 cache 管理,來清理老的 cache。我們在 activate 而不是 install 的時候進行的原因,是如果我們在 install 的時候進行清理,那么老的 service worker 仍然在控制頁面,他們依賴的緩存就失效了,因此就會突然被停止。
之前我們使用的緩存可以叫 my-site-cache-v1 ,我們想把這個拆封到多個緩存,一份給頁面使用,一份給博客文章使用。這意味著,install 步驟里,我們要創建兩個緩存: pages-cache-v1 和 blog-posts-cache-v1。在 activite 步驟里,我們需要刪除舊的 my-site-cache-v1。
下面的代碼會遍歷所有的緩存,并刪除掉不在 cacheWhitelist 數組(我們定義的緩存白名單)中的緩存。
self.addEventListener("activate", function(event) { var cacheWhitelist = ["pages-cache-v1", "blog-posts-cache-v1"]; event.waitUntil( caches.keys().then(function(cacheNames) { return Promise.all( cacheNames.map(function(cacheName) { if (cacheWhitelist.indexOf(cacheName) === -1) { return caches.delete(cacheName); } }) ); }) ); });
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/62107.html
摘要:是瀏覽器和服務器之間的腳本,主要作用是攔截請求,修改響應,以及一些其他的作用。這是出于安全因素的考慮。這個注冊的過程是發生在之外的。在安裝完成,激活之前,它不會攔截任何請求。將會始終攔截請求,重啟頁面也是為了這個。 pwa-之service worker 基本概念pwa-之service worker 離線文件處理 學習service worker 基本概念 在本章,將涵蓋以下內容 ...
摘要:是瀏覽器和服務器之間的腳本,主要作用是攔截請求,修改響應,以及一些其他的作用。這是出于安全因素的考慮。這個注冊的過程是發生在之外的。在安裝完成,激活之前,它不會攔截任何請求。將會始終攔截請求,重啟頁面也是為了這個。 pwa-之service worker 基本概念pwa-之service worker 離線文件處理 學習service worker 基本概念 在本章,將涵蓋以下內容 ...
摘要:需要提前掌握的基本使用檢測是否存在,創建緩存總對象。之后更新后的啟動并觸發事件。此時,當前頁面生效的依然是老版本的,新的會進入狀態。當頁面關閉之后,老的會被干掉,新的接管頁面一旦新的生效后會觸發事件。 前言: 看到一篇講解service worker的文章, 基礎講的還不錯, 所以轉了以后作為自己的參考 Service Worker是什么 service worker 是獨立于當前頁面...
摘要:當下比較火,而是實現的一項關鍵技術,今天我們一起了解下關于的一些基礎知識和適用場景。資源查找順序為從左向右,找到資源則返回,未找到則繼續尋找,直至最終獲取資源。借助,真正讓應用變得流行,也許就在不久的將來。 當下PWA比較火,而Service Worker是實現PWA的一項關鍵技術,今天我們一起了解下關于Service Worker的一些基礎知識和適用場景。 什么是Server Wor...
摘要:的生命周期的生命周期與頁面完全分離。換句話說,這個將為這個域中的所有內容接收事件。這不是必要的,但絕對是推薦的。新的將啟動并且安裝事件將被移除。使用,可以很容易被劫持連接并偽造響應。后臺同步允許延遲操作,直到用戶具有穩定的連接。 這是專門探索 JavaScript 及其所構建的組件的系列文章的第8篇。 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! 如果你錯過了前...
閱讀 2570·2021-11-23 09:51
閱讀 3120·2019-08-30 15:54
閱讀 1070·2019-08-30 14:14
閱讀 3542·2019-08-30 13:59
閱讀 1393·2019-08-29 17:09
閱讀 1468·2019-08-29 16:24
閱讀 2848·2019-08-29 15:43
閱讀 911·2019-08-29 12:45