同时清单4.4中的代码是个有趣的示例,它并没有展示出 Service Workers 的真正能力。我们会在这个示例的基础上更进一步,返回我们自定义的 HTTP 响应。
代码清单 4.5
self.addEventListener('fetch',function(event){ ❶if (/\.jpg$/.test(event.request.url)) { ❷event.respondWith(newResponse('<p>This is a response that comes from your service worker!</p>',{headers:{'Content-Type':'text/html'} ❸}); );}});
❶ 为 fetch 事件添加事件监听器
❷ 检查传入的 HTTP 请求是否是 JPEG 类型的图片
❸ 创建自定义 Response 并作出相应地响应
在清单4.5中,代码通过监听 fetch 事件的触发来拦截任何 HTTP 请求。接下来,它判断传入请求是否是 JPEG 文件,如果是的话,就使用自定义 HTTP 响应进行响应。使用 Service Workers ,你能够创建自定义 HTTP 响应,包括编辑响应首部。此功能使得 Service Workers 极其强大,同时也可以理解为什么它们需要通过 HTTPS 请求才能获取。想象一下,如果不是这样的话,黑客动动手指便可以完成一些恶意的操作!
4.2.1 Service Worker 生命周期
就在本书开头的第1章中,你了解过了 Service Worker 生命周期以及在它构建 PWA 时所扮演的角色。再来仔细看一遍下面的图。
Figure 4.1
图4.1 Service Worker 生命周期
看过上面的图,你会想到当用户第一次访问网站的时候,并不会有激活的 Service Worker 来控制页面。只有当 Service Worker 安装完成并且用户刷新了页面或跳转至网站的其他页面,Service Worker 才会激活并开始拦截请求。
为了更清楚地解释这个问题,我们想象一下,一个单页应用 (SPA) 或一个加载完成后使用 AJAX 进行交互的网页。当注册和安装 Service Worker 时,我们将使用到目前为止在本书中所介绍的方法,页面加载后发生的任何 HTTP 请求都将被忽略。只有当用户刷新页面,Service Worker 才会激活并开始拦截请求。这并不理想,你希望 Service Worker 能尽快开始工作,并包括在 Service Worker 未激活期间所发起的这些请求。
如果你想要 Service Worker 立即开始工作,而不是等待用户跳转至网站的其他页面或刷新本页面,有一个小技巧,你可以用它来立即激活你的 Service Worker 。
代码清单 4.6
清单4.6中的代码重点在于 Service Worker 的 install 事件里。通过使用 skipWaiting() 函数,最终会触发 activate 事件,并告知 Service Worker 立即开始工作,而无需等待用户跳转或刷新页面。
Figure 4.2
图4.2 self.skipWaiting() 会使 Service Worker 解雇当前活动的 worker 并且一旦进入等待阶段就会激活自身
skipWaiting() 函数强制等待中的 Service Worker 被激活 。self.skipWaiting() 函数还可以与 self.clients.claim() 一起使用,以确保底层 Service Worker 的更新立即生效。
下面清单4.7中的代码可以结合 skipWaiting() 函数,以确保 Service Worker 立即激活自身。
代码清单 4.7
同时使用清单4.6和4.7中的代码,可以快速激活 Service Worker。如果你的网站在页面加载后会发起复杂的 AJAX 请求,那么这些功能对你来说是完美的。如果你的网站主要是静态页面,而不是在页面加载后发起 HTTP 请求,那么你可能不需要使用这些功能。