Service Worker API - 位于 Web 应用程序、浏览器和网络之间的代理服务器
服务工作线程基本上充当位于 Web 应用程序、浏览器和网络 (如果可用) 之间的代理服务器。它们旨在支持创建有效的离线体验、拦截网络请求并根据网络是否可用采取适当的操作,以及更新驻留在服务器上的数据。它们还将允许访问推送通知和后台同步 API。
服务工作线程的概念和用法
服务工作线程是针对源和路径注册的事件驱动型工作线程。它采用 JavaScript 文件的形式,可以控制与之关联的网页/站点,拦截和修改导航和资源请求,并以非常精细的方式缓存资源,使您能够完全控制应用程序在某些情况下(最明显的情况是网络不可用时)的行为。
服务工作线程在工作线程上下文中运行:因此它没有 DOM 访问权限,并且运行在与支持您的应用程序的主 JavaScript 不同的线程上,因此它是非阻塞的。由于是完全异步的,所以服务工作线程内部不能使用同步的 XHR、Web 存储等接口。
出于安全原因,Service Worker 仅在 HTTPS 中运行。如果是网络请求被修改,对中间人攻击敞开大门,将会产生非常糟糕的后果。在 Firefox 中,Service Worker API 也是隐藏的,当用户处于隐私浏览模式时无法使用。
注意: 在 Firefox 上,为了测试,您可以通过 HTTP 运行服务工作线程(不安全);只需勾选 Firefox DevTools 选项 / 设备菜单中的 在 HTTP 中启用服务工作线程(当工具箱打开时) 选项。
注意: 与以前在这方面的尝试(如AppCache)不同,服务工作线程不会对您试图做的事情做出假设,而是在这些假设不完全正确时中断。相反,服务工作线程为您提供了更精细的控制。
注意: 服务工作线程中 promises,使用率较高,一般会等待响应,响应后会返回成功或失败动作。Promises 体系结构非常适合这一点。
注册
首先使用 ServiceWorkerContainer.register()
方法注册服务工作线程。如果成功,您的服务工作线程将被下载到客户端,并尝试安装 / 激活用户在整个源站内或您指定的子集内访问的 URL。
如果成功,您的服务人员将被下载到客户端,并尝试安装 / 激活(如下所示)用户在整个源站内或您指定的子集内访问的 URL。
下载、安装和激活
此时,您的服务工作线程将遵循以下生命周期:
- 下载
- 安装
- 激活
当用户第一次访问由服务工作线程控制的站点 / 页面时,立即下载服务工作线程。
在此之后,在下列情况下更新:
- 导航到指定范围的页面。
- 在服务工作线程上触发了一个事件,并且在过去 24 小时内没有下载。
当发现下载的文件是新的 - 不同于现有服务工作线程(按字节比较),或者是此页面 / 站点的第一个服务工作线程时,将尝试安装。
如果这是首次启用服务工作线程,则会尝试安装,然后在成功安装后将其激活。
如果有可用的现有服务工作器,则新版本将在后台安装,但尚未激活 - 此时称为_等待中的工作器_。仅当不再加载任何仍在使用旧服务工作线程的页面时,才会激活它。一旦没有要加载的页面,新的服务工作线程就会激活 (成为_活动工作线程_)。使用 ServiceWorkerGlobalScope.skipWaiting()
可以更快地激活,活动工作线程可以使用 Clients.Claime()
来声明现有页面。
您可以侦听 install
事件;一个标准的操作是让您的服务工作线程做好准备,以便在此事件触发时使用它,例如,使用内置存储 API 创建一个缓存,并在其中放置用于脱机运行应用程序所需的资产。
还有一个 activate
事件。此事件激发的时间点通常是清理旧缓存和与以前版本的服务工作线程相关联的其他内容的好时机。
您的服务工作线程可以使用 FetchEvent
事件响应请求。您可以使用 FetchEvent.RespondWith()
方法以任何您想要的方式修改对这些请求的响应。
注意: 由于
install
/activate
事件可能需要一段时间才能完成,服务工作线程规范提供了一个waitUntil()
方法。在带有 Promise 的install
或activate
事件上调用后,fetch
、push
等函数事件将等待 Promise 成功解析。
有关如何构建第一个基本实例的完整教程,请阅读使用服务工作线程。
其他用例想法
服务工作线程还可用于以下用途:
- 后台数据同步。
- 响应来自其他来源的资源请求。
- 接收计算成本较高的数据 (如地理位置或陀螺仪) 的集中更新,因此多个页面可以使用一组数据。
- 用于开发目的的 CoffeeScript、Less、CJS/AMD 等模块的客户端编译和依赖管理。
- 后台服务的钩子。
- 基于特定 URL 模式的自定义模板。
- 性能增强,例如预取用户在不久的将来可能需要的资源,例如相册中接下来的几张图片。
未来,服务工作线程将能够为网络平台做许多其他有用的事情,使其更接近本地应用的生存能力。有趣的是,其他规范可以也将开始使用服务工作线程上下文,例如:
接口
Cache
表示作为 ServiceWorker
生命周期的一部分缓存的 Request
/Response
对象对的存储。
CacheStorage
表示 Cache
对象的存储。 它提供了一个 ServiceWorker
可以访问的所有命名缓存的主目录,并维护字符串名称到相应的 Cache
对象的映射。
Client
表示服务工作线程客户端的作用域。服务工作线程客户端可以是浏览器上下文中的文档,也可以是由活动工作线程控制的 SharedWorker
。
Clients
表示包含 Client
对象列表的容器;它是访问当前来源的活动服务工作线程客户端的主要方式。
ExtendableEvent
扩展在 ServiceWorkerGlobalScope
上调度的 install
和 activate
事件的生存期,作为服务工作线程生命周期的一部分。它确保了在升级数据库模式并删除过时的缓存条目等之前,不会将任何功能事件(如 FetchEvent
)分派给 ServiceWorker
。
ExtendableMessageEvent
在服务工作线程上触发的 Message
事件的事件对象 (当在 ServiceWorkerGlobalScope
上从另一个上下文接收到通道消息时) - 扩展此类事件的生存期。
FetchEvent
传递到 onfetch
处理程序的参数,FetchEvent
表示在 ServiceWorker
的 ServiceWorkerGlobalScope
上调度的 fetch 操作。 它包含有关请求和结果响应的信息,并提供 FetchEvent.respondWith()
方法,该方法允许我们向受控页面提供任意响应。
InstallEvent
传递到 onInstall
处理程序的参数, InstallEvent
接口表示在 ServiceWorker
的 ServiceWorkerGlobalScope
上调度的安装操作。作为 ExtendableEvent
的子类,它确保安装过程中不会调度 FetchEvent
这样的功能事件。
NavigationPreloadManager
提供使用服务工作线程管理资源预加载的方法。
Navigator.serviceWorker
返回一个 ServiceWorkerContainer
对象,该对象提供对关联文档] 的 ServiceWorker
对象的注册、删除、升级和通信的访问。
NotificationEvent
传入到 onNotificationClick
处理程序的参数,NotificationEvent
接口表示在 ServiceWorker
的 ServiceWorker
上调度的通知点击事件。
ServiceWorker
表示服务工作线程。多个浏览上下文 (例如页面、工作进程等) 可以关联相同的 ServiceWorker
对象。
ServiceWorkerContainer
提供一个对象,将 Service Worker 表示为网络生态系统中的一个整体单元,包括注册、注销和更新 Service Worker 以及访问 Service Worker 状态及其注册的设施。
ServiceWorkerGlobalScope
表示服务工作线程的全局执行上下文。
MessageEvent
表示发送到 ServiceWorkerGlobalScope
的消息。
ServiceWorkerRegistration
表示服务工作线程的注册。
SyncEvent
表示在 ServiceWorker 的 ServiceWorkerGlobalScope
上调度的同步操作。
SyncManager
提供用于注册和列出同步注册的接口。
WindowClient
表示服务工作线程客户端的作用域,该服务工作线程客户端是浏览器上下文中的文档,由活动工作线程控制。这是一种特殊类型的 Client
对象,具有一些可用的其他方法和属性。
规范
规范 |
---|
Service Workers |