摘要:而一個文件名表明將只捕獲在下的請求。包含請求主體其被包含在對象中。該方法將首先緩存響應但隨后在后臺網絡請求。被用來提供響應針對請求。一旦這個異步操作完成后操作將終止。
翻譯:jsdt
原文標題:Understanding Service Workers
原文鏈接:http://blog.88mph.io/2017/07/...
聲明:轉載請指明出處。
在網絡早期,很難想象在用戶離線的時候一個網頁可以訪問。你總需要一直在線。
鏈接網絡吧,伙伴們都在這,不要離開了。
但隨著移動互聯網的出現,以及這個世界上越來越多的地區連接上網絡,參差不齊的網絡連接速度在現代web用戶中越來越普遍。
因此,對于與網站來說,研究如何使用戶不受到網絡鏈接限制能力,使他們在離線的時候也能訪問變得越來越有價值。
AppCache最初被引入作為html5的標準一部分,目的是作為web離線應用的解決方案之一。它包括HTML和javascript,由一個可以寫聲明性語語言的,緩存manifest配置文件進行管理。
Service workers提供了一個不會過時的,程序命令式的,針對離線web問題的解決方案,取代了聲明式的AppCache。
Service workers以持久的方式執行代碼,后臺進程的方式運行在瀏覽器中(意思是說不會影響js線程的執行),代碼是事件驅動的,意味著在Service workers中事件被觸發是因為外在的行為。
文章的剩余部分主要講述了Service workers當中的事件,作為分析開始,你首先需要知道,在你的web app中需要注冊service worker。
注冊下面的代碼介紹了在客戶端瀏覽器中怎樣注冊service worker。下面register的執行方式放在你的web app中的某處即可。
if (navigator.serviceWorker) { navigator.serviceWorker.register("/sw.js") .then(registration => { console.log("congrats. scope is: ", registration.scope); }) .catch(error => { console.log("sorry", error); }); }
上面代碼作用是告訴瀏覽器哪里去找Service Worke的實現。瀏覽器找到sw.js文件,將其保存為一個 Service Worker放在可以訪問到的域中。在sw.js中包含了怎么處理Service Worker生命周期中的一些事件。
上面圖示當中顯示一個已經注冊的service worker 在Chrome DevTools上。
它設置了你的ServiceWorker的作用范圍。文件名/sw.js意味著SW的范圍是項目的根路徑的URL(或http://localhost:3000/)。這意味著在根路徑下的任何請求將是可見的,對于SW被觸發的事件來說。
而一個文件名/js/sw.js表明將只捕獲在 http://localhost:3000/js下的請求。
作為一種選擇,你也可以通過傳遞參數的方式給register方法, 來顯式的設置SW的作用域范圍
navigator.serviceWorker.register("/sw.js", { scope: "/js" }).Event Handlers
既然你的Service Worker已經注冊,是時候去實現事件處理在Service Worker的各個生命周期階段。
Install Eventinstall事件在第一次成功注冊Service Worker時觸發,或者在Service Worke文件(/sw.js)更新(瀏覽器會自動檢測到更新)的時候。
install事件是有用的邏輯,在你想執行的Service Worker初始化期間,它是一次性的操作。一個常見的用例是在安裝步驟時加載緩存的文件。
這里是一個例子,一個安裝事件處理程序,它將數據添加到緩存中
const CACHE_NAME = "cache-v1"; const urlsToCache = [ "/", "/js/main.js", "/css/style.css", "/img/bob-ross.jpg", ]; self.addEventListener("install", event => { caches.open(CACHE_NAME) .then(cache => { return cache.addAll(urlsToCache); }); });
urlsToCache包含了一系列我們想添加到緩存中的url。
caches是一個全局的CacheStorage對象,通過這個對象可以管理你的緩存在瀏覽器中。
我們調用open方法以獲得確切的我們想使用的緩存對象。
cache.addAll接受URLs集合,然后遍歷發送一系列的request,然后存儲response在緩存中。它使用request body 作為每個緩存的key。addAll的參考文檔。
Cached data 在Chrome DevTools中
Fetch eventFetch事件被觸發在每次web頁面發出請求的時候。當它被觸發時,您的service worker有能力“攔截”請求,并決定如何返回——不管是緩存數據,抑或是一個實際的網絡請求響應。
下面的例子說明了cache-first策略:任何緩存的數據,在相匹配的請求中將被首先發送,而沒有一個網絡請求。只有在沒有緩存數據時才會有網絡請求。
self.addEventListener("fetch", event => { const { request } = event; const findResponsePromise = caches.open(CACHE_NAME) .then(cache => cache.match(request)) .then(response => { if (response) { return response; } return fetch(request); }); event.respondWith(findResponsePromise); });
request包含請求主體,其被包含在FetchEvent對象中。它是用來在緩存中查找匹配響應。
cache.match將試圖找到一個緩存來響應相匹配的指定請求。如果匹配不到,promise將解析為undefined。我們檢查這種情況,調用執行fetch方法在這種情況下,這會導致產生一個網絡請求并且返回一個promise。
FetchEvent對象上有一個特殊的方法event.respondWith,對于瀏覽器的請求我們可以使用這個方法返回一個相應。這個函數接受一個promise參數,返回一個response。
緩存策略fetch事件非常重要,因為只有通過這個方法你才能定義緩存策略。也就是說,你可以決定何時使用緩存數據,何時使用網絡數據。
Service Workers的美妙之處在于他是一個攔截requests的初級api,允許你返回自己定制的response。這給了我們是使用緩存還是網絡數據的自由。這里有幾個基本的緩存策略,你可以使用它們讓你的web app變得更好。
mdn是一個非常方便的文檔資源,他上面介紹了計重不同的緩存策略。這里也有一個Jake Archibald寫的 The Offline Cookbook,
,里面介紹了一些緩存策略,與mdn上相比有相同的,也有不同的。
在上面的示例中,我們演示了一個基本的cache-first策略。下面是一個我找到的適用于自己的項目的例子:緩存和更新策略。該方法將首先緩存響應,但隨后在后臺網絡請求。來自于這個后臺請求的response被用于更新緩存中的值,以便下次更新響應提供訪問。
self.addEventListener("fetch", event => { const { request } = event; event.respondWith(caches.open(CACHE_NAME) .then(cache => cache.match(request)) .then(matching => matching || fetch(request))); event.waitUntil(caches.open(CACHE_NAME) .then(cache => fetch(request) .then(response => cache.put(request, response)))); });
event.respondWith 被用來提供響應針對請求。通過它,我們開啟一個緩存,并從緩存中尋找匹配的response,如果緩存中匹配不到,就通過網絡來相應。
隨后,我們調用event.waitUntil,解析Promise在Service Worker結束之前。在這里我們發送一個網絡請求,然后緩存響應。一旦這個異步操作完成后,waitUntil操作將終止。
Activate Eventactivate是一個記錄事件,在你更新service worker文件,執行清理或者維護先前版本的service worker時,這個事件非常重要。
當你更新你的service worker文件(/sw.js)時,瀏覽器能探測到這種改變并顯示在Chrome DevTools:
你的service worker 正等在被激活
當web頁面關閉,再次重啟打開,瀏覽器將用新的service worker取代舊的service worker,并且依次觸發activate,install事件。如果你需要清理緩存或執行維護service worker的舊版本,激活事件是實現需求的最佳時機。
Sync eventsync事件可以讓你延遲網絡任務,直到用戶連接。它實現的功能通常被稱為后臺同步。這是有用的,可以確保任何網絡任務,在用戶開始在離線模式,然后又恢復網絡鏈接模式時順利執行。
這里有一個例子演示后臺任務,你只需要在你的js代碼中注冊一個同步事件,在其中做一些相應的處理在你的service worker中:
// app.js navigator.serviceWorker.ready .then(registration => { document.getElementById("submit").addEventListener("click", () => { registration.sync.register("submit").then(() => { console.log("sync registered!"); }); }); });
在這里我們聲明了一個按鈕上 的click事件通過調用sync.register在ServiceWorkerRegistration 對象上。
基本上,你想要確保在任何時候網絡連接上時實現一些操作,需要注冊一個類似上面的同步事件。
你想要實現的操作可能類似發送一個評論,獲取用戶數據等等都將被定義在Service Worker的事件處理器中。
// sw.js self.addEventListener("sync", event => { if (event.tag === "submit") { console.log("sync!"); } });
在這里我們監聽一個sync事件,檢查SyncEvent對象上的tag,看是否匹配我們submit。
如果在sync已經注冊的情況下,聲明sync多次,此時sync事件只會執行一次。
對于這個例子,如果用戶離線,并點擊按鈕七次,當恢復網絡鏈接,所有同步注冊執行優先級將會提高,并執行一次。
在那種情況下,你可能想針對每種同步點擊事件做不同的標識處理。
同步事件什么時候被觸發?如果用戶在線,同步事件無論是什么任務,都會立即執行,沒有任何延遲。
如果用戶離線,同步事件會盡可能快的被觸發在恢復網絡連接的時候。
你可以試試,驗證一下上面的結論在你的chrome中,再試之前確保斷開網路連接,檢查Chrome DevTools中的network選項。
想要了解更多信息,參考這篇文檔,抑或是background syncs. 同步事件很多瀏覽器不支持(僅僅chrome中有提到),一定會發生變化,所以持續關注。
通知推送通知推送是service worker中一個能夠使用的特性,與此先關的是瀏覽器上的一個push api
當談到網絡推送通知,在工作中涉及到兩種技術:通知和推送消息。
通知通知在service worker中是一個非常簡單容易實現的特性
// app.js // ask for permission Notification.requestPermission(permission => { console.log("permission:", permission); }); // display notification function displayNotification() { if (Notification.permission == "granted") { navigator.serviceWorker.getRegistration() .then(registration => { registration.showNotification("this is a notification!"); }); } }
// sw.js self.addEventListener("notificationclick", event => { // notification click event }); self.addEventListener("notificationclose", event => { // notification closed event });
你首先需要向用戶請求獲取權限在web頁面中。從那以后,你可以切換通知,處理某些事件,比如當用戶關閉一個通知。
消息推送消息推送牽涉到利用瀏覽器提供的push api,以及后端的實現。如何實現push api可以寫成一篇獨立的文章。但是基本的邏輯如下:
它是一個復雜和輕微難懂的流程,具體闡述不在本文范圍內,如果你想了解更多,推薦這篇文章 introduction to push notifications
題外話后面還有一小節闡述Ember和service worker的結合應用,這個我并不感興趣,就略過了,如果Ember換成vue或react就好啦。接下我打算寫一篇實戰例子。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84965.html
摘要:基本上是使用現代技術構建的網站但是體驗上卻像一個移動,在年,谷歌工程師和創造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗。檢查谷歌瀏覽器的和現在重載你的并且打開,到選項去查看面板,確保這個選項是勾選的。 Web開發多年來有了顯著的發展。它允許開發人員部署網站或Web應用程序并在數分鐘內為全球數百萬人服務。只需一個瀏覽器,用戶可以輸入URL就可以訪問Web應用程序了。隨著 Prog...
摘要:基本上是使用現代技術構建的網站但是體驗上卻像一個移動,在年,谷歌工程師和創造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗。檢查谷歌瀏覽器的和現在重載你的并且打開,到選項去查看面板,確保這個選項是勾選的。 Web開發多年來有了顯著的發展。它允許開發人員部署網站或Web應用程序并在數分鐘內為全球數百萬人服務。只需一個瀏覽器,用戶可以輸入URL就可以訪問Web應用程序了。隨著 Prog...
摘要:基本上是使用現代技術構建的網站但是體驗上卻像一個移動,在年,谷歌工程師和創造了。此后谷歌就一直致力于讓能給用戶像原生一般的體驗。檢查谷歌瀏覽器的和現在重載你的并且打開,到選項去查看面板,確保這個選項是勾選的。 Web開發多年來有了顯著的發展。它允許開發人員部署網站或Web應用程序并在數分鐘內為全球數百萬人服務。只需一個瀏覽器,用戶可以輸入URL就可以訪問Web應用程序了。隨著 Prog...
摘要:離線存儲數據的建議對尋址資源,使用這是的一部分。在到達儲量限制之前,兩種存儲機制都會一直進行存儲。則沒有對存儲量做出限制,只是在之后會彈出提醒。是異步的基于回調函數,但它同樣不支持。也是異步的基于回調函數,在和中可以工作雖然使用的是同步。 拖拖拉拉好久,終于把個人博客整出來了。鳴謝 @pinggod。 厚著臉安利一下,地址是 http://www.wemlion.com/。歡迎訪問,歡...
摘要:離線存儲數據的建議對尋址資源,使用這是的一部分。在到達儲量限制之前,兩種存儲機制都會一直進行存儲。則沒有對存儲量做出限制,只是在之后會彈出提醒。是異步的基于回調函數,但它同樣不支持。也是異步的基于回調函數,在和中可以工作雖然使用的是同步。 拖拖拉拉好久,終于把個人博客整出來了。鳴謝 @pinggod。 厚著臉安利一下,地址是 http://www.wemlion.com/。歡迎訪問,歡...
閱讀 2448·2021-10-08 10:17
閱讀 1823·2021-09-06 15:02
閱讀 2538·2019-08-29 17:30
閱讀 2663·2019-08-29 13:24
閱讀 1521·2019-08-29 11:12
閱讀 3337·2019-08-28 17:52
閱讀 666·2019-08-26 11:30
閱讀 3575·2019-08-26 11:01