日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Service Work

發布時間:2025/4/16 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Service Work 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

在2014年,W3C公布了service worker的草案,service worker提供了很多新的能力,使得web app擁有與native app相同的離線體驗、消息推送體驗。
service worker是一段腳本,與web worker一樣,也是在后臺運行。作為一個獨立的線程,運行環境與普通腳本不同,所以不能直接參與web交互行為。native app可以做到離線使用、消息推送、后臺自動更新,service worker的出現是正是為了使得web app也可以具有類似的能力。

?

service worker可以:

  • 后臺消息傳遞
  • 網絡代理,轉發請求,偽造響應

  • 離線緩存

  • 消息推送

  • ?… …

  • 本文以資源緩存為例,說明一下service worker是如何工作的。

    生命周期

    先來看一下一個service worker的運行周期


    上圖是service worker生命周期,出處http://www.html5rocks.com/en/tutorials/service-worker/introduction/

    圖中可以看到,一個service worker要經歷以下過程:

    ? ? 1. ?安裝

    ? ? 2. ?激活,激活成功之后,打開chrome://inspect/#service-workers可以查看到當前運行的service worker

    ? ? ?? ?

    ? ? 3. 監聽fetch和message事件,下面兩種事件會進行簡要描述

    ? ? 4. 銷毀,是否銷毀由瀏覽器決定,如果一個service worker長期不使用或者機器內存有限,則可能會銷毀這個worker

    fetch事件

    在頁面發起http請求時,service worker可以通過fetch事件攔截請求,并且給出自己的響應。
    w3c提供了一個新的fetch api,用于取代XMLHttpRequest,與XMLHttpRequest最大不同有兩點:

    ? ? ?1. fetch()方法返回的是Promise對象,通過then方法進行連續調用,減少嵌套。ES6的Promise在成為標準之后,會越來越方便開發人員。

    ? ? ? 2.?提供了Request、Response對象,如果做過后端開發,對Request、Response應該比較熟悉。前端要發起請求可以通過url發起,也可以使用Request對象發起,而且Request可以復用。但是Response用在哪里呢?在service worker出現之前,前端確實不會自己給自己發消息,但是有了service worker,就可以在攔截請求之后根據需要發回自己的響應,對頁面而言,這個普通的請求結果并沒有區別,這是Response的一處應用。

    下面是在http://www.sitepoint.com/introduction-to-the-fetch-api/中,作者利用fetch api通過fliker的公開api獲取圖片的例子,注釋中詳細解釋了每一步的作用:

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    /* 由于是get請求,直接把參數作為query string傳遞了 */

    var URL = 'https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=your_api_key&format=json&nojsoncallback=1&tags=penguins';

    ?

    function fetchDemo() {

    ??// fetch(url, option)支持兩個參數,option中可以設置header、body、method信息

    ??fetch(URL).then(function(response) {

    ????// 通過promise 對象獲得相應內容,并且將響應內容按照json格式轉成對象,json()方法調用之后返回的依然是promise對象

    ????// 也可以把內容轉化成arraybuffer、blob對象

    ????return response.json();

    ??}).then(function(json) {

    ????// 渲染頁面

    ????insertPhotos(json);

    ??});

    }

    ?

    fetchDemo();

    ?

    fetch api與XMLHttpRequest相比,更加簡潔,并且提供的功能更全面,資源獲取方式比ajax更優雅。兼容性方面:chrome 42開始支持,對于舊瀏覽器,可以通過官方維護的polyfill支持。

    message事件

    頁面和serviceWorker之間可以通過posetMessage()方法發送消息,發送的消息可以通過message事件接收到。

    這是一個雙向的過程,頁面可以發消息給service worker,service worker也可以發送消息給頁面,由于這個特性,可以將service worker作為中間紐帶,使得一個域名或者子域名下的多個頁面可以自由通信。

    這里是一個小的頁面之間通信demohttps://nzv3tos3n.qnssl.com/message/msg-demo.html

    利用service workder緩存文件

    下面介紹一個利用service worker緩存離線文件的例子
    準備index.js,用于注冊service-worker

    ?

    1

    2

    3

    4

    5

    6

    7

    if (navigator.serviceWorker) {

    ????navigator.serviceWorker.register('service-worker.js').then(function(registration) {

    ????????console.log('service worker 注冊成功');

    ????}).catch(function (err) {

    ????????console.log('servcie worker 注冊失敗')

    ????});

    }

    ?

    在上述代碼中,注冊了service-worker.js作為當前路徑下的service worker。由于service worker的權限很高,所有的代碼都需要是安全可靠的,所以只有https站點才可以使用service worker,當然localhost是一個特例。
    注冊完畢,現在開始寫service-worker.js代碼。
    根據前面的生命周期圖,在一個新的service worker被注冊以后,首先會觸發install事件,在service-workder.js中,可以通過監聽install事件進行一些初始化工作,或者什么也不做。
    因為我們是要緩存離線文件,所以可以在install事件中開始緩存,但是只是將文件加到caches緩存中,真正想讓瀏覽器使用緩存文件需要在fetch事件中攔截

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    var cacheFiles = [

    ????'about.js',

    ????'blog.js'

    ];

    self.addEventListener('install', function (evt) {

    ????evt.waitUntil(

    ????????caches.open('my-test-cahce-v1').then(function (cache) {

    ????????????return cache.addAll(cacheFiles);

    ????????})

    ????);

    });

    ?

    首先定義了需要緩存的文件數組cacheFile,然后在install事件中,緩存這些文件。
    evt是一個InstallEvent對象,繼承自ExtendableEvent,其中的waitUntil()方法接收一個promise對象,直到這個promise對象成功resolve之后,才會繼續運行service-worker.js。
    caches是一個CacheStorage對象,使用open()方法打開一個緩存,緩存通過名稱進行區分。
    獲得cache實例之后,調用addAll()方法緩存文件。

    這樣就將文件添加到caches緩存中了,想讓瀏覽器使用緩存,還需要攔截fetch事件

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    // 緩存圖片

    self.addEventListener('fetch', function (evt) {

    ????evt.respondWith(

    ????????caches.match(evt.request).then(function(response) {

    ????????????if (response) {

    ????????????????return response;

    ????????????}

    ????????????var request = evt.request.clone();

    ????????????return fetch(request).then(function (response) {

    ????????????????if (!response && response.status !== 200 && !response.headers.get('Content-type').match(/image/)) {

    ????????????????????return response;

    ????????????????}

    ????????????????var responseClone = response.clone();

    ????????????????caches.open('my-test-cache-v1').then(function (cache) {

    ????????????????????cache.put(evt.request, responseClone);

    ????????????????});

    ????????????????return response;

    ????????????});

    ????????})

    ????)

    });

    ?

    通過監聽fetch事件,service worker可以返回自己的響應。

    首先檢緩存中是否已經緩存了這個請求,如果有,就直接返回響應,就減少了一次網絡請求。否則由service workder發起請求,這時的service workder起到了一個中間代理的作用。

    service worker請求的過程通過fetch api完成,得到response對象以后進行過濾,查看是否是圖片文件,如果不是,就直接返回請求,不會緩存。

    如果是圖片,要先復制一份response,原因是request或者response對象屬于stream,只能使用一次,之后一份存入緩存,另一份發送給頁面。
    這就是service worker的強大之處:攔截請求,偽造響應。fetch api在這里也起到了很大的作用。

    ?

    service worker的更新很簡單,只要service-worker.js的文件內容有更新,就會使用新的腳本。但是有一點要注意:舊緩存文件的清除、新文件的緩存要在activate事件中進行,因為可能舊的頁面還在使用之前的緩存文件,清除之后會失去作用。

    ?

    在初次使用service worker的過程中,也遇到了一些問題,下面是其中兩個

    問題1. 運行時間

    service worker并不是一直在后臺運行的。在頁面關閉后,瀏覽器可以繼續保持service worker運行,也可以關閉service worker,這取決與瀏覽器自己的行為。所以不要定義一些全局變量,例如下面的代碼(來自https://jakearchibald.com/2014/service-worker-first-draft/):

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    var hitCounter = 0;

    ?

    this.addEventListener('fetch', function(event) {

    ??hitCounter++;

    ??event.respondWith(

    ????new Response('Hit number ' + hitCounter)

    ??);

    });

    ?

    返回的結果可能是沒有規律的:1,2,1,2,1,1,2….,原因是hitCounter并沒有一直存在,如果瀏覽器關閉了它,下次啟動的時候hitCounter就賦值為0了
    這樣的事情導致調試代碼困難,當你更新一個service worker以后,只有在打開新頁面以后才可能使用新的service worker,在調試過程中經常等上一兩分鐘才會使用新的,比較抓狂。

    問題2. 權限太大

    當service worker監聽fetch事件以后,對應的請求都會經過service worker。通過chrome的network工具,可以看到此類請求會標注:from service worker。如果service worker中出現了問題,會導致所有請求失敗,包括普通的html文件。所以service worker的代碼質量、容錯性一定要很好才能保證web app正常運行。

    ?

    參考文章:

    ?1.?http://www.html5rocks.com/en/tutorials/service-worker/introduction/

    ?2.?http://www.sitepoint.com/introduction-to-the-fetch-api/

    ?3.?https://developer.mozilla.org/en-US/docs/Web/API/InstallEvent

    ?4.?https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent

    ?5.?https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage

    轉載于:https://my.oschina.net/wanjubang/blog/839436

    總結

    以上是生活随笔為你收集整理的Service Work的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。