Service Workers簡(jiǎn)介(一)

——evilrescuer翻譯自Matt Gaunt
寫(xiě)的[Service Workers: an Introduction](收錄于 谷歌開(kāi)發(fā)者)(https://developers.google.com/web/fundamentals/primers/service-workers/)

豐富的離線體驗(yàn)坏瘩,定期后臺(tái)同步椭懊,推送通知 (一般這是原生app做的事)現(xiàn)在正在走向web. Service workers 提供了這些功能的技術(shù)基礎(chǔ)添谊。

一启盛、service worker是什么

service worker是一個(gè)腳本圆米,由瀏覽器在背后默默地運(yùn)行育瓜,獨(dú)立于web頁(yè)面。它給一些不需要頁(yè)面顯示和用戶操作的功能 開(kāi)啟了一扇新的大門(mén)。目前仑荐,它已經(jīng)包含了像推送通知后臺(tái)同步這樣的功能。在未來(lái)纵东,service workers可能會(huì)支持其他功能粘招,如定期同步或者地理防護(hù)。這次我們介紹的它的核心功能是攔截和處理網(wǎng)絡(luò)請(qǐng)求篮迎,包括以編程方式管理響應(yīng)緩存男图。

地理防護(hù)(geofencing)是軟件程序中的一種功能,它運(yùn)用全球定位系統(tǒng)(GPS)或射頻識(shí)別(RFID)規(guī)定地理邊界甜橱。 地理柵欄是一種虛擬的邊界逊笆。 地理柵欄程序允許管理員設(shè)置觸發(fā)器,所以當(dāng)設(shè)備越過(guò)地理柵欄進(jìn)出管理員規(guī)定的邊界時(shí)岂傲,會(huì)有警告短信(SMS)或電子郵件發(fā)出难裆。

service worker之所以讓我們振奮人心,是因?yàn)樗С蛛x線體驗(yàn)镊掖,完全由開(kāi)發(fā)者控制乃戈。

在service worker之前,我們用一個(gè)API做離線體驗(yàn):AppCache亩进。但AppCache有一些問(wèn)題症虑,service workers在設(shè)計(jì)時(shí),就盡量避免了這些問(wèn)題归薛。

關(guān)于service worker谍憔,我們需要知道:

  • 它是一個(gè) JavaScript 線程, 所以它不能直接接觸DOM. service worker 可以與一些頁(yè)面通信(這些頁(yè)面通過(guò)postMessage接口發(fā)出信息),而這些頁(yè)面可以操作DOM(如果需要的話)

  • Service worker 是一個(gè)可編程的網(wǎng)絡(luò)代理主籍,它允許你控制網(wǎng)絡(luò)如何從你的頁(yè)面發(fā)出請(qǐng)求习贫。

  • 不使用時(shí)會(huì)停止運(yùn)行,在你下一次需要時(shí)又會(huì)重啟千元。所以苫昌,在一個(gè)service worker的 onfetchonmessage處理函數(shù)里,你不能指望會(huì)有一個(gè)全局的service worker的狀態(tài)標(biāo)志幸海。如果你的確需要存儲(chǔ)并復(fù)用service worker的狀態(tài)祟身,它提供了一個(gè)API可以用來(lái)連接DB: IndexedDB API

  • Service workers廣泛使用promises,所以如果你是一個(gè)promises小白物独,你需要停下來(lái)袜硫,先讀讀Promise的這篇文章:Promises介紹

service worker的生命周期

service worker有完全獨(dú)立于web頁(yè)面的生命周期。

如果你要給你的網(wǎng)站使用service worker议纯,你需要在指定的頁(yè)面的JavaScript中注冊(cè)父款。注冊(cè)service worker后溢谤,瀏覽器會(huì)默默地在背后安裝service worker瞻凤。

在安裝這一步中憨攒,你可能需要緩存一些靜態(tài)資源。如果所有這些文件緩存成功阀参,則service worker安裝成功肝集;相反,如果有文件下載緩存失敗蛛壳,則安裝步驟失敗杏瞻,此時(shí)service worker不會(huì)被激活 (沒(méi)裝上)。但是別擔(dān)心衙荐,稍后它還是會(huì)繼續(xù)安裝的捞挥。

安裝完成后,會(huì)啟動(dòng)激活步驟忧吟,此時(shí)非常適合用來(lái)處理 舊緩存砌函。

激活成功后,service worker會(huì)控制其范圍內(nèi)的所有頁(yè)面溜族。第一次注冊(cè)service worker的頁(yè)面讹俊,會(huì)等到頁(yè)面加載成功后,才會(huì)接受控制煌抒。一旦service worker在控制頁(yè)面仍劈,它只會(huì)有兩種狀態(tài):要么停止運(yùn)行,要么處理頁(yè)面中的fetch和message事件(當(dāng)頁(yè)面中有網(wǎng)絡(luò)請(qǐng)求或消息時(shí))寡壮。

下面這種圖顯示了service worker第一次安裝時(shí)的生命周期:


二贩疙、前提條件

1.瀏覽器支持

Chrome, Firefox and Opera支持Service workers。Microsoft Edge 現(xiàn)在也支持了(支持情況). 甚至連 Safari 也列入未來(lái)的開(kāi)發(fā)計(jì)劃诬像。最新的支持情況可以看這個(gè)網(wǎng)站: 《Serviceworker準(zhǔn)備好了嗎》屋群。

2.需要HTTPS

如果你要用service worker,本地開(kāi)發(fā)對(duì)HTTPS沒(méi)有要求坏挠。但是芍躏,如果你要部署到服務(wù)器,你必須要用HTTPS降狠。

service worker 可以劫持連接对竣、構(gòu)造和過(guò)濾返回。你可能可以正確地用這些特征榜配,但是中間人可不這么做否纬。為了防止中間人利用這些特點(diǎn),你可以為HTTPS頁(yè)面注冊(cè)service worker蛋褥。所以临燃,我們知道瀏覽器通過(guò)網(wǎng)絡(luò)接收到的service worker沒(méi)有被篡改過(guò)。

GitHub 頁(yè)面 就是建立在 HTTPS之上的, 所以是一個(gè)很好的放Demo的地方。

如果你想把HTTPS加到你到服務(wù)器里膜廊,你需要一個(gè)TLS證書(shū)乏沸,并在服務(wù)器上加上配置。配置多種多樣爪瓜,可以參考Mozilla的SSL配置生成器的最佳實(shí)踐蹬跃。

三、注冊(cè)service worker

在頁(yè)面上注冊(cè)铆铆,代碼如下:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/sw.js').then(function(registration) {
      // Registration was successful
      console.log('ServiceWorker registration successful with scope: ', registration.scope);
    }, function(err) {
      // registration failed :(
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}

以上代碼檢查service worker服務(wù)是否可用蝶缀,在一旦頁(yè)面load完成完成后,注冊(cè)/sw.js薄货。

你可以在頁(yè)面加載后直接調(diào)用register()翁都,瀏覽器會(huì)自動(dòng)處理service worker是不是已經(jīng)注冊(cè)過(guò)并且根據(jù)情況處理。

register() 的一個(gè)需要注意的點(diǎn)是service worker的文件位置谅猾。這個(gè)例子中荐吵,文件位置在域名的根位置底下。這說(shuō)明service worker的作用域是整個(gè)源赊瞬。換句話說(shuō)先煎,service worker會(huì)接受到這個(gè)域名下到所有fetch事件。如果我們注冊(cè)到是/example/sw.js這個(gè)位置巧涧,那service worker就只會(huì)接收到URL以/example/ 開(kāi)頭(比如 /example/page1/, /example/page2/)的 fetch事件

現(xiàn)在薯蝎,你可以看到 service worker已經(jīng)可用“可以通過(guò) chrome://inspect/#service-workers 和你的站點(diǎn)確認(rèn)占锯。

當(dāng)service worker第一次實(shí)施時(shí),如果你只是為了看生命周期缩筛,也可以通過(guò)chrome://serviceworker-internals查看具體內(nèi)容消略。但以后可能會(huì)被chrome://inspect/#service-workers取代。

在瀏覽器的隱私模式下瞎抛,service worker也可用艺演。但是,窗口之間是不互相影響的桐臊。隱私模式下的注冊(cè)和緩存胎撤,會(huì)在窗口被關(guān)閉時(shí)被清理。

四断凶、安裝service worker

注冊(cè)流程后伤提,我們說(shuō)說(shuō)安裝service worker的代碼。
最基礎(chǔ)的例子认烁,你需要給安裝事件一個(gè)callback函數(shù)肿男,并指定需要緩存的文件介汹。

self.addEventListener('install', function(event) {
  // 處理安裝步驟
});

在callback函數(shù)內(nèi)部,我們需要注意:

  • 開(kāi)啟緩存
  • 緩存一些文件
  • 檢查文件是否緩存成功
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);
      })
  );
});

這里舶沛,我們調(diào)用了caches.open()開(kāi)啟緩存痴昧。之后,我們調(diào)用cache.addAll()冠王,并傳入一個(gè)文件數(shù)組,指定了我們需要緩存的文件舌镶。這是一個(gè)promises鏈(caches.open() and cache.addAll())柱彻。event.waitUntil()方法通過(guò)promise得到安裝時(shí)間,安裝是否成功餐胀。

如果所有這些文件都被成功緩存哟楷,那service worker就被成功安裝上了。但是否灾,只要有一個(gè)文件下載失敗卖擅,整個(gè)安裝步驟就失敗了。這取決于你定義的這些文件墨技,所以你要小心對(duì)待這個(gè)文件列表惩阶,因?yàn)樗赡軐?dǎo)致你的service worker安裝不上。

這僅僅是一個(gè)例子扣汪,你也可以在安裝事件中處理其他任務(wù)断楷,或者不設(shè)置安裝事件的監(jiān)聽(tīng)器。

下篇會(huì)說(shuō)到如何返回一個(gè)緩存請(qǐng)求如何更新service worker 以及 service worker的一些不好的東西崭别。
《 Service Workers簡(jiǎn)介(二) 》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末冬筒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子茅主,更是在濱河造成了極大的恐慌舞痰,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诀姚,死亡現(xiàn)場(chǎng)離奇詭異响牛,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)赫段,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)娃善,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人瑞佩,你說(shuō)我怎么就攤上這事聚磺。” “怎么了炬丸?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵瘫寝,是天一觀的道長(zhǎng)蜒蕾。 經(jīng)常有香客問(wèn)我,道長(zhǎng)焕阿,這世上最難降的妖魔是什么咪啡? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮暮屡,結(jié)果婚禮上撤摸,老公的妹妹穿的比我還像新娘。我一直安慰自己褒纲,他們只是感情好准夷,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著莺掠,像睡著了一般衫嵌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上彻秆,一...
    開(kāi)封第一講書(shū)人閱讀 52,785評(píng)論 1 314
  • 那天楔绞,我揣著相機(jī)與錄音,去河邊找鬼唇兑。 笑死酒朵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扎附。 我是一名探鬼主播耻讽,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼帕棉!你這毒婦竟也來(lái)了针肥?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤香伴,失蹤者是張志新(化名)和其女友劉穎慰枕,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體即纲,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡具帮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了低斋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜂厅。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖膊畴,靈堂內(nèi)的尸體忽然破棺而出掘猿,到底是詐尸還是另有隱情,我是刑警寧澤唇跨,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布稠通,位于F島的核電站衬衬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏改橘。R本人自食惡果不足惜滋尉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望飞主。 院中可真熱鬧狮惜,春花似錦、人聲如沸碌识。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)丸冕。三九已至,卻和暖如春薛窥,著一層夾襖步出監(jiān)牢的瞬間胖烛,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工诅迷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佩番,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓罢杉,卻偏偏與公主長(zhǎng)得像趟畏,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子滩租,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361