___|  _ \   |  |    |   |_ _|\ \     / ____|
 |     |   |  |  |    |   |  |  \ \   /  __|
 |   | |   | ___ __|  ___ |  |   \ \ /   |
\____|\___/     _|   _|  _|___|   \_/   _____| 

 --- A GOPHER-LIKE INTERFACE FOR HIVE BLOCKCHAIN ---

PWA 学习笔记之 Service Workers

BY: @semlinker | CREATED: Jan. 18, 2018, 10:08 a.m. | VOTES: 1 | PAYOUT: $0.05 | [ VOTE ]

Service worker 是一个在 Web 应用程序后台运行的脚本。它不需要 DOM,实际上它甚至不能访问 DOM。Service worker 运行在与 UI 线程独立的线程中,因此它们在运行时不会阻塞 UI 线程。Service worker 的意义在于它充当了你的应用和互联网之间的中介。然后它会执行你设定的任何功能,最后通过消息传递将结果返回给应用程序。

出于安全考虑,Service workers 只能由 HTTPS 承载,因为修改网络请求的能力暴露给中间人攻击会非常危险。需要注意的是在 Firefox 浏览器的用户隐私模式,Service Worker 不可用。

> 在开发过程中,可以通过 localhost 使用服务工作线程,但如果要在网站上部署服务工作线程,需要在服务器上设置 HTTPS。
>
> 使用服务工作线程,您可以劫持连接、编撰以及过滤响应。 这是一个很强大的工具。您可能会善意地使用这些功能,但中间人可会将其用于不良目的。 为避免这种情况,可仅在通过 HTTPS 提供的页面上注册服务工作线程,如此我们便知道浏览器接收的服务工作线程在整个网络传输过程中都没有被篡改。 —— 服务工作线程:简介

Service workers 拥有强大的能力,它还可以用来做以下这些事情:

使用 Service Worker

self.addEventListener('install', (event) => {
    console.log('service worker installed', event);
});

self.addEventListener('activate', (event) => {
  console.log('service worker activated', event);
});
(() => {
  if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
      navigator.serviceWorker.register('service-worker.js')
        .then((registration) => {
          console.log('registered');
          console.log(registration);
      },(err) => {
        console.log(err);
      }); 
   });
  } else {
    alert('当前的浏览器不支持 Service Worker');
  } 
})();




    Service Worker Demo




My name is Semlinker, I Love PWA!


如果你是使用 WebStorm,可以直接运行以上的 index.html 文件。或使用 Web Server for Chrome 插件、其它 Web 服务器运行 index.html 文件。

在浏览器中成功打开 index.html 文件后,在控制台中能看到以下输出信息,具体如下图所示:

[IMAGE: https://steemitimages.com/DQmcR6xAHuAHyLKKceEzedXei8HvhwhFBvKPvTE4MWDVCiF/sw-registration.jpg]

图中 scriptURL 字段表示 service worker 脚本的加载地址,state 字段表示当前 service worker 的状态,scope 字段表示当前已激活 service worker 的作用域。我们可以在注册 service worker 时,通过设置第二个参数的 scope 属性来设置 service worker 的作用域

Service worker 的简单示例已经运行起来了,接下来我们来了解一下调试 service worker 的相关知识。

调试 Service Worker

打开 Chrome 开发者工具,选择 Application Tab 页,然后选择左侧 Application 菜单的 Service Workers 子菜单项。

[IMAGE: https://steemitimages.com/DQmX2Ko7BUQkmYvvBYdt36PKhfQYEZGFTNC6GCa41FCfHwb/dev-sw-tab.png]

图中红框中是一系列复选框,它们的作用如下:

此外图中绿色状态指示灯旁边的 ID,是用于表示当前 service worker 的 ID。上面我们已经介绍了 Update on reload 选项,接下来我们来体验一下如何更新 service worker。

更新 Service Worker

更新 service-worker.js 文件,具体内容如下:

self.addEventListener('install', (event) => {
    console.log('New service worker installed', event);
});

self.addEventListener('activate', (event) => {
    console.log('New service worker activated', event);
});

保存 service-worker.js 文件后,在浏览器中重新刷新一下 index.html 页面。这时浏览器控制台只输出了两条消息,少了一条消息,没有输出 New service worker activated 这条消息。现在让我们在看一下当前 service worker 的状态,具体如下图所示:

[IMAGE: https://steemitimages.com/DQmVvPkb6Dh6HypAEfcJY7m4daJLGqaFRvsb5SNMKBohocH/sw-update.jpg]

通过观察上图,我们发现当更新 service-worker.js 后,刷新当前页面更新后的 service worker 并不会马上进入激活状态,而是进入等待激活的状态。那么如何让更新后的 service worker 立即进入激活状态呢?相信一些小伙伴已经注意到了 skipWaiting 这个链接,顾名思义它用于跳过等待。当点击这个链接后,控制台将会输出我们预期的信息:

New service worker activated 

其实上图也表示了当前站点下同时存在两个 servicer worker,一个处于激活状态(运行状态),另一个处于非激活状态(等待状态)。如果你想同一个时刻,只有一个 service worker,我们也可以通过使用 skipWaiting 方法来实现强制更新。这意味着当更新 service worker 时我们将跳过等待状态,即会移除已激活的 service worker,然后激活新的 service worker。

具体代码如下:

self.addEventListener('install', (event) => {
    self.skipWaiting();
    console.log('Update service worker installed', event);
});

self.addEventListener('activate', (event) => {
    console.log('Update service worker activated', event);
});

本文已经介绍了如何使用、调试及更新 Service Worker,最后我们再来简单介绍一下 Service Worker 的生命周期。

Service Worker 生命周期

Service Worker 拥有一个完全独立于 Web 页面的生命周期,前面我们已经介绍过 install 和 activate,完整的生命周期可以参考introduction-to-progressive-web-app-architectures

下一篇文章我们将介绍如何利用 fetch API、CacheStorage API 及 Service Worker 实现缓存控制,刚开始学习 PWA,以上内容有误之处,请小伙伴们多多指教。

参考资源

TAGS: [ #cn-programming ] [ #pwa ] [ #cn ]

Replies

@cn-naughty.boy | Jan. 18, 2018, 10:10 a.m. | Votes: 0 | [ VOTE ]

我也想成为你这样的码农!

[ BACK TO TRENDING ] [ BACK TO MENU ]
CMD>