首頁 >web前端 >js教程 >詳解javascript中的Service Workers!

詳解javascript中的Service Workers!

青灯夜游
青灯夜游轉載
2020-12-03 17:44:244053瀏覽

本篇文章跟大家介紹一下JavaScript API - Service Workers。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

詳解javascript中的Service Workers!

相關推薦:《程式設計入門

service worker 是什麼

Service Worker 是Chrome 團隊提出和力推的一個WEB API,用於給web 應用提供高級的可持續的後台處理能力。這項 WEB API 標準起草於 2013 年,於 2014 年納入 W3C WEB 標準草案,目前仍在草案階段。

Service Worker 最主要的特點是:在頁面中註冊並安裝成功後,運行於瀏覽器後台,不受頁面刷新的影響,可以監聽和截攔作用域範圍內所有頁面的HTTP 請求。

類似一個伺服器與瀏覽器之間的中間人角色,如果網站中註冊了service worker 那麼它可以攔截當前網站所有的請求,進行判斷(需要編寫相應的判斷程序),如果需要向伺服器發起請求的就轉給伺服器,如果可以直接使用快取的就直接返回快取不再轉給伺服器。從而大大提高瀏覽體驗。

詳解javascript中的Service Workers!

Service Worker 可以啟用先前原生應用程式專有的一組功能。 Service Worker 的初稿已於2014年發布,現在所有主流瀏覽器都支援它們。

就像已經指出的定義一樣,Service Worker 是網路代理。這意味著它們可以控制頁面中的所有網路請求,並且可以對其進行編程,使用快取的進行回應。

Service Worker 特點

  • 網站必須使用 HTTPS。除了使用本地開發環境調試時(如域名使用localhost)
  • 運行於瀏覽器後台,可以控制打開的作用域範圍下所有的頁面請求
  • 單獨的作用域範圍,單獨的運行環境和執行執行緒
  • 不能操作頁面DOM。但可以透過事件機制來處理

如何註冊Service Worker

註冊Service Worker 不需要太多程式碼,只需要一個用於Service Worker 程式碼的JS 文件,一般取名為service-worker.js

// 首先检查浏览器是否支持 Service Worker
if ('serviceWorker' in navigator) {
  navigator.serviceWorker
    .register('/sw/service-worker.js')
    .then(function(registration) {
      console.log(registration);
    })
    .catch(function(err) {
      console.log(err);
    });
}

其實關鍵程式碼只有一行:

navigator.serviceWorker.register('/sw/service-worker.js')

注意:

Service Worker 的註冊路徑決定了其scope 預設作用範圍。範例中service-worker.js 是在/sw 路徑下,這使得該Service Worker 預設只會收到/sw 路徑下的 fetch事件。如果存放在網站的根路徑下,則將會收到該網站的所有 fetcg事件。

如果希望改變它的作用域,可在第二個參數設定 scope範圍。範例中將其改為根目錄,即對整個網站生效。

另外應意識到這一點:Service Worker 沒有頁面作用域的概念,作用域範圍內的所有頁面請求都會被目前啟動的 Service Worker 所監控。

Service Worker 可以啟用哪些功能?

在本節中,我將進一步詳細介紹Service Worker的功能,包括一些小程式碼範例。

服務工作者啟用下列功能,這些功能也是PWA的核心:

  • #離線功能
  • 定期後台同步
  • 推播通知

離線功能

Service Worke 透過快取資源和攔截網路請求來提供離線功能,這些請求可以與先前快取的資源一起使用,而不是重新請求伺服器.

我們可以從中得到兩個步驟:

  • 預先快取
  • 從快取中處理請求

這兩個步驟都利用了Cache API,它由Web Workers 和瀏覽器使用,並且為我們提供了網路請求的儲​​存機制。

對 Web 和服務工作人員上下文的 localStorage 存取被阻止,以防止並發性問題。作為一種替代方案,IndexedDB 可以用於儲存大量資料。

預先快取

預先快取是一個術語,描述了在 Service Worker 處於啟動狀態之前下載和快取檔案。它是在 Service Worker 生命週期的「install 」步驟中完成的。一旦 Service Worker 處於啟動狀態,它將準備為快取中的檔案提供服務。

通常,我們要快取 Application Shell,這是運行網站所需的最少程式碼量。如果開發了本機應用程序,那麼這就是您將上傳到應用程式商店的程式碼包。這包括所有必需的基本JavaScript,HTML和圖片。

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(currentCache.offline).then(function(cache) {
      return cache.addAll([
        '/static/images/offline.svg',
        '/static/html/offline.html',
      ]);
    });
  );
});

從快取處理請求

#

在此阶段,我们已经将所有应用程序代码存储在缓存中,并且Service Worker 已处于激活即运行于浏览器后台。

现在唯一缺少的是监听 fetch 事件并从缓存中返回结果。可以通过 fetch 事件可以拦截到当前作用域范围内的 http/https 请求,并且给出自己的响应。结合 Fetch API ,可以简单方便地处理请求响应,实现对网络请求的控制。

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).then(function(response) {
      return response || fetch(event.request);
    })
  );
});

在本例中,我们尽可能使用缓存的内容进行响应。作为回退,我们发出一个网络请求。

这里实现了一个缓存优先降级处理的策略逻辑:监控所有 http 请求,当请求资源已经在缓存里了,直接返回缓存里的内容;否则使用 fetch API 继续请求,如果是 图片或 cssjs 资源,请求成功后将他们加入缓存中;如果是离线状态或请求出错,则降级返回预缓存的离线内容。

定期后台同步

正如在引言中已经提到的那样,Service Worker 与其他服务工作者在一个单独的线程上运行,所以即使关闭页面,它们也可以执行其代码。 此功能对于执行后台同步和提供推送通知很重要。

后台同步

用户离开页面后,后台同步通常用于同步数据。

例如,在手机上编辑文档后,我们写完会点击“保存”并离开页面。 如果在编辑文档期间连接断开,我们必须等待连接恢复才能保存文档。

后台同步的目的是解决这个问题,一旦连接重新建立,自动发送数据。

来看一个示例:

app.js

navigator.serviceWorker.ready.then((registration) => {
  return registration.sync.register('sync-save-document');
});

service-worker.js

self.addEventListener('sync', (event) => {
  if (event.tag === 'sync-save-document') {
    event.waitUntil(saveDocument());
  }
});

saveDocument是一个返回 Promise,如果被拒绝(例如由于网络问题),同步将自动重试。

要注意的一件事是,同步标记必须是唯一的。 例如,如果我要安排5个“message”类型的后台同步,则只有最后一个会通过。 因此,在这种情况下,每个标签都应具有唯一的标识符。

定期后台同步

定期后台同步解决与正常后台同步不同的问题。 该API可用于在后台更新数据,而不必等待用户。

这对很多应用程序都很有用。有了这项技术,用户可以在没有互联网连接的情况下阅读最新的新闻文章。

为了防止滥用这一功能,同步的频率取决于浏览器为每个网站设置的站点参与度分数。如果你经常打开一个网页应用,这个频率最多可以达到12个小时。

要实现此目的一个要求是,该网站已作为移动设备上的 PWA 安装并添加到主屏幕。

推送通知

Service Worker另一个类似本机的特性是推送通知。我们通常通过手机短信或社交媒体通知的形式知道它们,但它们也可以在台式电脑上使用。

Safari之外,所有主流浏览器都支持它们,而Safari对桌面应用程序有自己的实现。

要使用推送通知,需要设置一台服务器,该服务器会将通知推送给所有客户端。 由于Service Worker在后台在另一个线程上运行,因此即使页面当前未打开,用户也可以看到推送通知。

推送的实现有两步:

不同浏览器需要用不同的推送消息服务器。以 Chrome 上使用 Google Cloud Messaging<gcm></gcm> 作为推送服务为例,第一步是注册 applicationServerKey(通过 GCM 注册获取),并在页面上进行订阅或发起订阅。每一个会话会有一个独立的端点(endpoint),订阅对象的属性(PushSubscription.endpoint) 即为端点值。将端点发送给服务器后,服务器用这一值来发送消息给会话的激活的 Service Worker (通过 GCM 与浏览器客户端沟通)。

浏览器支持情况

詳解javascript中的Service Workers!

除了 Safari 和 IE/Edge,大部分现代浏览器都已经得到了支持。

总结

希望通过本文介绍基本概念和特性,可以让你更好地理解Service Worker

英文原文地址:https://felixgerschau.com/service-workers-explained-introduction-javascript-api/

作者: Felix Gerschau

译文地址:https://segmentfault.com/a/1190000027080988

想要查阅更多相关文章,请访问PHP中文网!!

以上是詳解javascript中的Service Workers!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除