当前位置: 首页 > Web前端 > HTML5

ServiceWorkers-JavaScriptAPI介绍

时间:2023-04-05 23:54:03 HTML5

作者:FelixGerschau译者:前端小智来源:FelixGerschau再次点赞,微信搜索【大千世界】,B站关注【前端小智】这个没有后台的大厂,但人有向上积极的心态。本文已收录到GitHubhttps://github.com/qq44924588...,文章已分类,也整理了很多我的文档和教程资料。最近开源了一个Vue组件,但是还不够完善。欢迎大家一起完善,也希望大家能给个star支持一下。谢谢。github地址:https://github.com/qq44924588...什么是ServiceWorker?ServiceWorker是Chrome团队提出并推广的一种WEBAPI,旨在为Web应用程序提供先进的、可持续的后台处理能力。WEBAPI标准起草于2013年,2014年被纳入W3CWEB标准草案,目前仍处于草案阶段。ServiceWorker的主要特点是:在页面上注册安装成功后,在浏览器后台运行,不受页面刷新的影响,可以监听和拦截范围内所有页面的HTTP请求。类似于服务器和浏览器之间的中间人角色,如果网站注册了serviceworker,它可以拦截当前网站的所有请求并进行判断(需要写相应的判断程序),如果需要向服务器发起请求,会转给服务器,如果服务器可以直接使用缓存,则直接返回缓存,不会转给服务器。从而大大提高浏览体验。ServiceWorkers启用了一组以前专用于本机应用程序的功能。ServiceWorkers的初稿于2014年发布,现在所有主流浏览器都支持它们。正如已经指出的定义,ServiceWorker是网络代理。这意味着它们控制对页面的所有网络请求,并且可以编程为使用缓存的响应。ServiceWorker特色网站必须使用HTTPS。除使用本地开发环境调试(如域名使用localhost)在浏览器后台运行外,可以控制打开作用域下的所有页面请求一个单独的作用域,单独的运行环境和执行线程无法操作页面DOM。但是可以通过事件机制来处理如何注册ServiceWorker注册ServiceWorker不需要太多代码,只需要一个ServiceWorker代码的JS文件,一般命名为service-worker.js//先查看浏览器是否支持ServiceWorkerif('serviceWorker'innavigator){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')注:ServiceWorker的注册路径决定了它默认范围。示例中service-worker.js在/sw路径下,这使得ServiceWorker默认只接收/sw路径下的fetch事件。如果存放在网站的根路径下,将接收到该网站的所有fetch事件。如果你想改变它的范围,你可以在第二个参数中设置范围。示例中改为根目录,对整个站点有效。还要注意一点:ServiceWorker没有页面作用域的概念,作用域内的所有页面请求都会被当前活跃的ServiceWorker监听。ServiceWorker可以启用哪些功能?在本节中,我将进一步详细介绍ServiceWorker的功能,包括一些小的代码示例。ServiceWorkers启用以下功能,这些功能也是PWA的核心:离线功能定期后台同步推送通知离线功能ServiceWorkers通过缓存资源和拦截可与先前缓存的资源一起使用的网络请求来提供离线功能,而不是重新请求服务器。我们可以从中得出两个步骤:PrecachingandServingRequestsfromCache这两个步骤都使用了CacheAPI,它被WebWorker和浏览器使用,并为我们提供了网络请求的存储机制。LocalStorage对Web和服务工作者上下文的访问被阻止以防止并发问题。作为替代方案,IndexedDB可用于存储大量数据。预缓存预缓存是描述在ServiceWorker处于活动状态之前下载和缓存文件的术语。它是在ServiceWorker生命周期的“安装”步骤中完成的。一旦serviceworker处于活动状态,它将准备好从缓存中提供文件。通常,我们希望缓存ApplicationShell,这是运行网站所需的最少代码量。如果您开发了本机应用程序,这就是您将上传到应用程序商店的代码包。这包括所有必需的基本JavaScript、HTML和图像。self.addEventListener('install',function(event){event.waitUntil(caches.open(currentCache.offline).then(function(cache){returncache.addAll(['/static/images/offline.svg','/static/html/offline.html',]);}););});处理来自缓存的请求在这个阶段,我们将所有应用程序代码存储在缓存中,并且ServiceWorker处于活动状态在浏览器的后台运行。现在唯一缺少的是监听fetch事件并从缓存中返回结果。你可以通过fetch事件拦截当前作用域内的http/https请求,并给出自己的响应。结合FetchAPI,可以简单方便的处理请求响应,实现对网络请求的控制。self.addEventListener('fetch',function(event){event.respondWith(caches.match(event.request).then(function(response){返回响应||fetch(event.request);}));});在此示例中,我们尽可能使用缓存内容进行响应。作为后备,我们发出网络请求。这里实现了一个缓存优先级和降级处理的策略逻辑:监听所有的http请求,当请求的资源已经在缓存中时,直接返回缓存中的内容;否则使用fetchAPI继续请求,如果是图片或者css、js资源,请求成功后将它们加入缓存;如果离线或者请求错误,会降级返回预先缓存的离线内容。周期性的后台同步正如介绍中已经提到的,ServiceWorker运行在与其他ServiceWorker不同的线程上,因此即使在页面关闭时它们也可以执行自己的代码。此功能对于执行后台同步和提供推送通知很重要。后台同步后台同步通常用于用户离开页面后同步数据。例如,我们在手机上编辑完一个文档后,会点击“保存”,写完就离开页面。如果在编辑文档时连接丢失,我们必须等待连接恢复才能保存文档。后台同步的目的是通过在重新建立连接后自动发送数据来解决这个问题。让我们看一个例子:app.jsnavigator.serviceWorker.ready.then((registration)=>{returnregistration.sync.register('sync-save-document');});service-worker.jself.addEventListener('sync',(event)=>{if(event.tag==='sync-save-document'){event.waitUntil(saveDocument());}});saveDocument是一个Promise,如果被拒绝(例如由于网络问题)则返回,同步将自动重试。需要注意的一件事是同步标记必须是唯一的。例如,如果我要安排5个“消息”类型的后台同步,则只有最后一个会通过。所以在这种情况下,每个标签都应该有一个唯一的标识符。定期后台同步定期后台同步解决的问题与普通后台同步不同。该API可用于在后台更新数据,而无需等待用户。这对许多应用程序很有用。有了这项技术,用户可以在没有互联网连接的情况下阅读最新的新闻文章。为防止滥用此功能,同步频率由浏览器为每个网站设置的网站参与度分数决定。如果您频繁打开Web应用程序,这个频率最多可达12小时。此功能的一个要求是该网站作为PWA安装在移动设备上并添加到主屏幕。推送通知ServiceWorker的另一个类似原生的功能是推送通知。我们通常以手机短信或社交媒体通知的形式了解它们,但它们也可以在台式电脑上使用。所有主流浏览器都支持它们,除了Safari,它有自己的桌面应用程序实现。要使用推送通知,您需要设置一个将通知推送给所有客户端的服务器。由于ServiceWorker在后台运行在另一个线程上,因此即使页面当前未打开,用户也可以看到推送通知。推送的实现有两个步骤:不同的浏览器需要使用不同的推送消息服务器。以GoogleCloudMessaging作为Chrome上的推送服务为例,第一步是注册applicationServerKey(通过GCM注册获得),在页面订阅或发起订阅。每个会话都有一个独立的端点(endpoint),订阅对象(PushSubscription.endpoint)的属性就是端点值。将端点发送到服务器后,服务器使用此值向会话的活动ServiceWorker发送消息(通过GCM与浏览器客户端通信)。浏览器支持除了Safari和IE/Edge,大多数现代浏览器都已经被支持。小结希望通过本文介绍的基本概念和特性,能够让大家对ServiceWorker有更好的理解。代码部署后可能存在的bug,无法实时获知。事后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的bug监控工具Fundebug。原文:https://felixgerschau.com/ser...每周更新交流文章。可以微信搜索“大千世界”阅读即时更新(比博文早一两篇)。这篇文章在GitHubhttps://github.com/qq449245884/xiaozhi已经收录,整理了很多我的文档。欢迎star和改进。可以参考考点面试。另外,关注公众号,后台会回复福利,看到福利就知道了。