使用服务工作人员管理网络请求和推送通知Use Service Workers to manage network requests and push notifications

服务工作者是一种特殊类型的 Web 工作线程,能够使用 API 截获、修改和响应所有网络 Fetch 请求。Service Workers are a special type of Web Worker with the ability to intercept, modify, and respond to all network requests using the Fetch API. 服务工作人员可以访问 API 和异步客户端数据存储(如) Cache IndexedDB 来存储资源。Service Workers can access the Cache API, and asynchronous client-side data stores, such as IndexedDB, to store resources.

注册服务工作线程Registering a Service Worker

与其他 Web 工作人员类似,服务工作人员必须存在于单独的文件中。Similar to other Web Workers, Service Workers must exist in a separate file. 注册服务工作线程时引用此文件,如以下代码段所示。You reference this file when registering the Service Worker, as shown in the following code snippet.

if ( "serviceWorker" in navigator ) {
    navigator.serviceWorker.register( "/serviceworker.min.js" );
}

新式浏览器为服务工作者提供不同级别的支持。Modern browsers provide different levels of support for Service Workers. 因此,最佳做法是在运行任何与服务工作器相关的代码之前测试对象 serviceWorker 是否存在。As such, it is a good practice to test for the existence of the serviceWorker object before running any Service Worker-related code. 在以上代码段中,使用位于网站根目录的文件注册服务 serviceworker.min.js 工作器。In the above code snippet, a Service Worker is registered using the serviceworker.min.js file located at the root of the site. 确保定义服务工作者的 JavaScript 文件位于您希望其管理 (的最高级别目录中,该目录称为 Service Worker) 。Ensure that the JavaScript file that defines your Service Worker exists in the highest-level directory that you want it to manage (which is referred to as the scope of the Service Worker). 在以前的代码段中,文件存储在根中,服务工作者管理域中的所有页面。In the previous code snippet, the file is stored in the root, and the Service Worker manages all pages in the domain. 如果服务工作器文件存储在目录中,则服务工作器的范围将是目录和 js js 任何子目录。If the Service Worker file was stored in a js directory, the scope of the Service Worker would be the js directory and any subdirectories. 最佳做法是,将服务工作器文件放在网站的根目录下,除非需要减小服务工作器的范围。As a best practice, place the Service Worker file in the root of your site, unless you need to reduce the scope of your Service Worker.

服务工作线程生命周期The Service Worker lifecycle

服务工作者的生命周期由多个步骤组成,每个步骤触发事件。The lifecycle of a Service Worker consists of multiple steps, with each step triggering an event. 可以将侦听器添加到这些事件中,以运行代码以执行一个操作。You can add listeners to these events to run code to perform an action. 以下列表提供服务工作者的生命周期和相关事件的高级别视图。The following list presents a high-level view of the lifecycle and related events of service workers.

  1. 注册服务工作线程。Register the Service Worker.

  2. 浏览器下载 JavaScript 文件,安装服务工作线程并触发 install 事件。The browser downloads the JavaScript file, installs the Service Worker, and triggers the install event. 可以使用该事件预缓存任何重要和长期的文件,如 CSS 文件、JavaScript 文件、徽标图像、脱机页面等 installYou can use the install event to pre-cache any important and long-lived files, such as CSS files, JavaScript files, logo images, offline pages, and so on from your website.

    self.addEventListener( "install", function( event ){
        console.log( "WORKER: install event in progress." );
    });
    
  3. 服务工作器被激活,这将触发 activate 事件。The Service Worker is activated, which triggers the activate event. 使用此事件清理过时的缓存。Use this event to clean up outdated caches.

    self.addEventListener( "activate", event => {
        console.log('WORKER: activate event in progress.');
    });
    
  4. 在刷新页面或用户导航到网站上的新页面时,服务工作线程已准备好运行。The Service Worker is ready to run when the page is refreshed or when the user navigates to a new page on the site. 如果要在不等待的情况下运行服务工作线程,请使用 self.skipWaiting() 事件期间 install 的方法。If you want to run the Service Worker without waiting, use the self.skipWaiting() method during the install event.

    self.addEventListener( "install", event => {
        self.skipWaiting();
        // …
    });
    
  5. 服务工作线程现在正在运行。The Service Worker is now running.

在服务工作者中使用提取Using fetch in Service Workers

在服务工作线程中使用的主要事件是 fetch 事件。The main event that you use in a Service Worker is the fetch event. 每次浏览器尝试访问服务工作器范围内的内容时,都会 fetch 运行该事件。The fetch event runs every time the browser attempts to access content within the scope of the Service Worker. 以下代码段演示如何将侦听器添加到提取事件。The following code snippet shows how to add a listener to the fetch event.

self.addEventListener( "fetch", event => {
  console.log('WORKER: Fetching', event.request);
});

在处理程序中,你可以控制请求是否进入网络、是否从缓存中 fetch 拉取,等等。Within the fetch handler, you may control whether a request goes to the network, pulls from the cache, and so on. 您采用的方法可能会因所请求的资源类型、更新频率以及应用程序特有的其他业务逻辑而异。The approach you take likely varies based upon the type of resource being requested, how frequently it is updated, and other business logic unique to your application. 下面是您可以执行哪些工作的示例:Here are a few examples of what you may do:

  • 如果可用,请从缓存返回响应,否则回退以通过网络请求资源。If available, return a response from the cache, otherwise fallback to request the resource over the network.
  • 从网络提取资源、缓存副本并返回响应。Fetch a resource from the network, cache a copy, and return the response.
  • 允许用户指定保存数据的首选项。Allow user's to specify a preference to save data.
  • 为某些图像请求提供占位符图像。Supply a placeholder image for certain image requests.
  • 直接在服务工作线程中生成响应。Generate a response directly in the Service Worker.

推送通知Push Notifications

服务工作人员可以向用户推送通知。Service workers can push notifications to users. 推送通知有助于提示用户在经过一段时间后重新使用您的应用程序。Push Notifications are helpful to prompt users to re-engage with your application after some time has elapsed. 有关详细信息,请导航到 推送通知演练和演示For more information, navigate to Push Notifications walkthrough and demo.

另请参阅See also

若要了解有关服务工作者的信息,请导航到以下相关主题列表。To learn more about Service Workers, navigate to the following list of related topics.