特点:.本质上充当服务器与浏览器之间的代理服务器(可以拦截全站的请求,并作出相应的动作->由开发者指定的动作).在web worker的基础上增加了离线缓存的能力.由事件驱动的,具有生命周期,其生命周期与页面无关(关联页面未关闭时,它也可以退出,没有关联页面,它也可以启动).可以访问cache和indexDB.完全异步,同步API(如XHR和localStorage)不能在service work中使用.只能为https承载.服务于多个页面的。(按照同源策略).不能缓存POST请求应用场景:.跟 Fetch 搭配,可以从浏览器层面拦截请求,做数据 mock;.跟 Fetch 和 CacheStorage 搭配,可以做离线应用;.跟 Push 和 Notification 搭配,可以做像 Native APP 那样的消息推送激活流程:.在navigator.serviceWorker.register进行注册后.用户首次访问service worker控制的网站或页面时,service worker会立刻被下载.无论它与现有service worker不同(字节对比),还是第一次在页面或网站遇到service worker,如果下载的文件是新的,安装就会尝试进行.安装成功后它会被激活.如果现有service worker已启用,新版本会在后台安装,但不会被激活,这个时序称为worker in waiting.直到所有已加载的页面不再使用旧的service worker才会激活新的service worker。只要页面不再依赖旧的service worker,新的service worker会被激活(成为active worker)。跳过等待:this.skipWaiting(); 跳过installing,直接接管老的service worker,触发activate,在self.addEventListener('install')中调用手动更新客户端:self.clients.claim(),在self.addEventListener('activate')中清除完旧缓存后调用.之后,在以下情况将会触发更新:.一个前往作用域内页面的导航.在 service worker 上的一个事件被触发并且过去 24 小时没有被下载基本使用:Service Worker 注册的代码是放在 HTML 的最后,如果页面加载时没有Service Worker,那么它所依赖的其他资源请求也不会触发 fetch 事件。1、注册service worker.如果注册成功,service worker就会被下载到客户端并尝试安装或激活,这将作用于整个域内用户可访问的URL,或者其特定子集navigator.serviceWorker.register(url,options)url:service worker文件的路径,路径是相对于 Origin ,而不是当前文件的目录的optiontsscope:表示定义service worker注册范围的URL ;service worker可以控制的URL范围。通常是相对URL。默认值是基于当前的location(./),并以此来解析传入的路径.假设你的sw文件放在根目录下位于/sw/sw.js路径的话,那么你的sw就只能监听/sw/*下面的请求,如果想要监听所有请求有两个办法,一个是将sw.js放在根目录下,或者是在注册是时候设置scope。如设置为/app/即app地址路径下的所有页面如/app/index.html;/app/main/index.html。`避免第一次打开页面就进行缓存,占用主线程的带宽,以及加剧对cpu和内存的使用if ('serviceWorker' in navigator) {window.addEventListener('load', function() {navigator.serviceWorker.register('/sw.js');});}if ('serviceWorker' in window.navigator) {navigator.serviceWorker.register('./sw.js', { scope: './' }).then(function (res) {res:ServiceWorkerRegistration实例}).catch(function (err) {console.log('fail', err);});注册多个service worker,但scope必须是不同的navigator.serviceWorker.register('./sw/sw.js', { scope: './sw' }).then(function (reg) {console.log('success', reg);})navigator.serviceWorker.register('./sw2/sw2.js', { scope: './sw2' }).then(function (reg) {console.log('success', reg);})}1.5、方法主线程中:(1)发送信息if ('serviceWorker' in window.navigator) {navigator.serviceWorker.register('./sw.js', { scope: './' }).then(function (reg) {方式一:.如果使用的scope不是Origin下使用.reg.active就是被注册后激活 Serivce Worker 实例.由于Service Worker的激活是异步的,因此第一次注册 Service Worker 的时候,Service Worker 不会被立刻激活, reg.active 为 nullreg.active.postMessage("this message is from page, to sw");方式二:确定当前serviceWorker已经激活安装完成navigator.serviceWorker.controller && navigator.serviceWorker.controller.postMessage("this message is from page");方式三:通过messageChannel});方式四:navigator.serviceWorker.register('service-worker.js');navigator.serviceWorker.ready.then( registration => {registration.active.postMessage("Hi service worker");});(2)销毁service workerif ('serviceWorker' in navigator) {//获取所有注册的service workernavigator.serviceWorker.getRegistrations().then(function(registrations) {for(let registration of registrations) {//安装在网页的service worker不止一个,找到我们的那个并删除if(registration && registration.scope === 'https://seed.futunn.com/'){registration.unregister(); //进行销毁}}});}(3)更新service workervar version = '1.0.1'navigator.serviceWorker.register('/sw.js').then((reg) => {if(localStorage.getItem('sw_version') !== version) {reg.update().then(() => {localStorage.setItem('sw_version', version)})}})在service worker脚本文件中:(1)发送消息this.addEventListener('message', function (event) {必须使用event.source进行发送,在其他能获取到的函数中也可以event.source.postMessage('this message is from sw.js, to page');});方式二:.通过窗口发送,即注册了该serviceWoker的页面的clients对象(即windows对象).client必须要接收到页面发送到serviceWorker的消息后才能发送消息this.clients.matchAll().then(client => {client[0].postMessage('this message is from sw.js, to page');})方式三:通过messageChannel2、监听在service worker脚本文件中(1)监听被下载安装this.addEventListener('install', function (event) {console.log('Service Worker install');});var CACHE_VERSION = 1;var CURRENT_CACHES = {prefetch: 'prefetch-cache-v' + CACHE_VERSION};self.addEventListener('install', function(event) {var urlsToPrefetch = ['./static/pre_fetched.txt','./static/pre_fetched.html','https://www.chromium.org/_/rsrc/1302286216006/config/customLogo.gif'];event.waitUntil(caches.open(CURRENT_CACHES['prefetch']).then(function(cache) {cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) {return new Request(urlToPrefetch, {mode: 'no-cors'});})).then(function() {console.log('All resources have been fetched and cached.');});}).catch(function(error) {console.error('Pre-fetching failed:', error);}));});(2)监听被激活.触发时可以清理旧缓存和旧的service worker关联的东西this.addEventListener('activate', function (event) {console.log('Service Worker activate');});(3)监听信息发送this.addEventListener('message', function (event) {console.log(event.data); });(4)监听浏览器请求this.addEventListener('fetch', function (event) {...}主线程监听(1)监听消息发送navigator.serviceWorker.addEventListener('message', function (e) {console.log(e.data); });(2)监听service worker是否改变navigator.serviceWorker.addEventListener('controllerchange', () => {window.location.reload();})3、记录service worker的生命周期if ('serviceWorker' in navigator) {$('#isSupport').text('支持');// 开始注册service workersnavigator.serviceWorker.register('./sw-demo-cache.js', {scope: './'}).then(function (registration) {$('#isSuccess').text('注册成功');var serviceWorker;if (registration.installing) {serviceWorker = registration.installing;$('#state').text('installing');} else if (registration.waiting) {serviceWorker = registration.waiting;$('#state').text('waiting');} else if (registration.active) {serviceWorker = registration.active;$('#state').text('active');}if (serviceWorker) {$('#swState').text(serviceWorker.state);serviceWorker.addEventListener('statechange', function (e) {$('#swState').append('&emsp;状态变化为' + e.target.state);});}}).catch (function (error) {$('#isSuccess').text('注册没有成功');});} else {$('#isSupport').text('不支持');}</script>4、离线背景同步.可以先将网络相关任务延迟到用户有网络的时候再执行.可以用于保证任何用户在离线的时候所产生对于网络有依赖的操作,最终可以在网络再次可用的时候抵达它们的目标。.离线期间所有相同事件只会触发一次,如果希望每一次点击都能触发 sync 事件,就需要在注册的时候赋予它们不同的tag。navigator.serviceWorker.ready  .then(registration => {document.getElementById('submit').addEventListener('click', () => {背景同步操作registration.sync.register('submit').then(() => {console.log('sync registered!');});});});service worker中:  self.addEventListener('sync', event => {  if (event.tag === 'submit') {console.log('sync!');}});5、最佳实践为了保证离线缓存的资源和真实资源一致,优先使用在线资源(即http请求),sw充当本地和线上服务器的代理服务器角色;当在线资源获取出错(服务器宕机,网络不可用等情况),则使用sw本地缓存优先从线上获取,获取之后设置缓存,以便下一次获取html出错时候再从本地缓存获取的是上一次获取的文件请求拦截:this.addEventListener('fetch', function (event) {if(event.request.method === 'POST') {event.respondWith(new Promise(resolve => {event.request.json().then(body => {console.log(body); // 用户请求携带的内容})resolve(new Response({ a: 2 })); // 返回的响应}))}}}self.addEventListener('fetch', function(event) {      event.respondWith(caches.match(event.request).then(function(response) {if (response) {return response;}return fetch(event.request).then(function(response) {return response;}).catch(function(error) {throw error;});}));});页面缓存:通过Cache Stroage或indexDB进行存储因为oninstall和onactivate完成前需要一些时间,service worker标准提供一个waitUntil方法,当oninstall或者onactivate触发时被调用,接受一个promiseevent.waitUntil.只能在 Service Worker 的 install 或者 activate 事件中使用;.如果传递了一个 Promise 给它,那么只有当该 Promise resolved 时,Service Worker 才会完成 install;.如果 Promise rejected 掉,那么整个 Service Worker 便会被废弃掉。因此,cache.addAll 里面,只要有一个资源获取失败,整个 Service Worker 便会失效。event.respondWith.只能在 Service Worker 的 fetch 事件中使用;.返回一个Promise,当传入的 Promise resolved 之后,才会将对应的 response 返回给浏览器。.resolve的内容为 Response对象、a network error(1)静态资源化缓存this.addEventListener('install', function (event) {event.waitUntil(caches.open('sw_demo').then(function (cache) {return cache.addAll(['/style.css','/panda.jpg','./main.js'])}));});(2)动态资源缓存this.addEventListener('fetch', function (event) {event.respondWith(caches.match(event.request).then(res => {return res ||fetch(event.request)  获取真实资源并缓存.then(responese => {需要克隆一份,因为请求和响应流只能被读取一次,为了给浏览器返回响应并且还要把它缓存起来,我们不得不克隆一份const responeseClone = responese.clone();caches.open('sw_demo').then(cache => {cache.put(event.request, responeseClone);})return responese;}).catch(err => {console.log(err);});}))});

代码示例:
资源加载错误,导航错误页

self.addEventListener('fetch', function(event) {event.respondWith(caches.match(event.request).then(function(response) {return response || fetch(event.request);}).catch(function() {return caches.match('/error.html');}));
});

错误降级、清除worker

  window.addEventListener('load', function() {const sw = window.navigator.serviceWorkerconst killSW = window.killSW || falseif (!sw) {return}if (!!killSW) {sw.getRegistration('/serviceWorker').then(registration => {// 手动注销registration.unregister();// 清除缓存window.caches && caches.keys && caches.keys().then(function(keys) {keys.forEach(function(key) {caches.delete(key);});});})} else {// 表示该 sw 监听的是根域名下的请求sw.register('/serviceWorker.js',{scope: '/'}).then(registration => {// 注册成功后会进入回调console.log('Registered events at scope: ', registration.scope);}).catch(err => {console.error(err)})}});

更新、清除缓存

// sw.js 更换缓存命名空间
this.addEventListener('install', function (event) {console.log('install');event.waitUntil(caches.open('sw_demo_v2').then(function (cache) { // 更换缓存命名空间return cache.addAll(['/style.css','/panda.jpg','./main.js'])}))
});//新的命名空间
const cacheNames = ['sw_demo_v2'];// sw.js 校验过期的缓存进行清除
this.addEventListener('activate', function (event) {event.waitUntil(caches.keys().then(keys => {return Promise.all[keys.map(key => {if (!cacheNames.includes(key)) {console.log(key);return caches.delete(key); // 删除不在白名单中的其他命名空间的 Cache Stroage}})]}))
});

雨雀官网的缓存

self.assets = ["https://gw.alipayobjects.com/os/chair-script/skylark/common.b4c03be5.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/common.e2d71ce8.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__components__Explore__Recommend~p__explore__routers__Docs~p__explore__routers__Repos~p_~d6257766.aa1bcc43.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__components__Explore__Recommend~p__explore__routers__Docs~p__explore__routers__Repos~p_~d6257766.fac19d5b.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/c__Lakex~p__editor__routers__TextEditor.9defba11.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/c__Lakex~p__editor__routers__TextEditor.3a98afb8.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__bookRepo__routers.244d87f7.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__bookRepo__routers.ef3c862f.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/c__Lakex.acd5cec4.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/c__Lakex.653d1e93.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/layout__MainLayout.ae548301.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/layout__MainLayout.c0075e36.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__bookRepo__model.511a24e3.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__bookRepo__routers__EditCustomIndex.d4fbfe9e.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__bookRepo__routers__EditCustomIndex.28048163.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__bookRepo__routers__ShareExpired.8113c1a2.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__bookRepo__routers__ShareExpired.b6dff962.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__bookRepo__routers__SharePassword.1a6ae926.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__bookRepo__routers__SharePassword.f76c7685.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__components__Explore__Events.6d43e196.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__components__Explore__Events.979d04c6.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__components__Explore__Recommend.ab8c57cb.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__components__Explore__Recommend.ac025d9d.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__model.2d27d4bc.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__App.4d4a0a8c.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__App.08fcac15.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__CollabBooks.40627926.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__CollabBooks.91d8d56d.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Collects.0a516ca7.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Collects.b5f172fe.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Dashboard.5f89b7f3.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Dashboard.be7c1714.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Explore.b51bb073.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Groups.198f522b.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Groups.ad67b3b7.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__History.086ddd9c.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__History.5387e7a8.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__MyBooks.40627926.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__MyBooks.61608f6e.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Notes.a878e2d7.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Notes.ffe2cc7a.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Recycles.ab448ca1.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__dashboard__routers__Recycles.3434b09c.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__doc__model__page.424fcfd2.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__doc__routers.66f72a35.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__doc__routers.39267068.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__doc__routers__version.e7b71a05.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__doc__routers__version.186ff53b.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__model.7ef254a2.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__Asl.60282b53.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__Asl.fa585dad.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__TextEditor.f413dbfc.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__TextEditor.81c5d11d.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__board.591d841b.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__board.832f1003.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__doc.a1ccd84d.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__doc.e652cf65.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__embed.500645af.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__embed.743631c5.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__embed_extreme.5563bfd4.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__embed_extreme.88434cbe.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__sheet.8a86af45.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__sheet.2daf2fb0.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__show.75463f8e.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__show.14157f9c.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__table.60aad9c2.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__editor__routers__table.29a799ed.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__model.263db0b2.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Books.cfc93cd2.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Books.8ffd07d8.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Custom.710dc957.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Custom.604bf4aa.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Embed.daf129f3.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Embed.1a8cd333.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Error403.8113c1a2.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Error403.e426da8e.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Group.a1fbd1b1.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Group.aca6ba40.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Members.c73713ca.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Members.fc9d4e92.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Migrate.e821f2d6.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Migrate.c5718315.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Recycles.724821a4.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Recycles.9b99a94d.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Statistics.e849f2e3.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Statistics.e2b4dc68.async.js", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Upgrade.a42075c1.chunk.css", "https://gw.alipayobjects.com/os/chair-script/skylark/p__group__routers__Upgrade.d80c9df1.async.js", "https://gw.alipayobjects.com/os/lib/??react/16.13.1/umd/react.production.min.js,react-dom/16.13.1/umd/react-dom.production.min.js,react-dom/16.13.1/umd/react-dom-server.browser.production.min.js,moment/2.24.0/min/moment.min.js", "https://gw.alipayobjects.com/as/g/larkgroup/lake-codemirror/6.0.2/CodeMirror.js", "https://gw.alipayobjects.com/as/g/larkgroup/lark-sheet/11.0.20/lark-sheet.css", "https://gw.alipayobjects.com/a/g/lark/??immutable/3.8.2/immutable.min.js", "https://gw.alipayobjects.com/as/g/larkgroup/lark-sheet/11.0.20/lark-sheet.js"];
self.resourceBase = "https://gw.alipayobjects.com/os/chair-script/skylark/";self.addEventListener("install", (e => {//预加载常用资源Array.isArray(self.assets) && e.waitUntil(caches.open("v1").then((e => {e.addAll(self.assets)})))
})), self.addEventListener("activate", (e => {Array.isArray(self.assets) && caches.open("v1").then((e => {e.keys().then((t => {t.forEach((t => {//过期资源释放self.assets.includes(t.url) || e.delete(t)}))}))}))
}));
const r = [self.resourceBase, "https://at.alicdn.com/t/", "https://gw.alipayobjects.com/os/"];
self.addEventListener("fetch", (e => {//拦截资源,满足上述域名,优先使用缓存,否则使用网络下载资源并更新资源。r.some((t => e.request.url.startsWith(t))) && e.respondWith(caches.match(e.request).then((t => t && 200 === t.status ? t : fetch(e.request).then((t => {if (200 !== t.status) return t;const r = t.clone();return caches.open("v1").then((t => {t.put(e.request, r)})), t})).catch((() => {})))))
}))

缓存、缓存更新、拦截请求

// 缓存静态资源文件列表
let cacheFiles = ['./test.js','./index.html','./src/img/yy.png'
]
// serviceworker使用版本
let __version__ = 'cache-v2'// 缓存静态资源
self.addEventListener('install', function (evt) {// 强制更新sw.jsself.skipWaiting()evt.waitUntil(caches.open(version).then(function (cache) {return cache.addAll(cacheFiles)}))
})// 缓存更新
self.addEventListener('active', function (evt) {evt.waitUntil(caches.keys().then(function (cacheNames) {return Promise.all(cacheNames.map(function (cacheName) {if (cacheName !== version) {return caches.delete(cacheName)}}))}))
})// 请求拦截
self.addEventListener('fetch', function (evt) {console.log('处理fetch事件:', evt.request.url)evt.respondWith(caches.match(evt.request).then(function (response) {if (response) {console.log('缓存匹配到res:', response)return response}console.log('缓存未匹配对应request,准备从network获取', caches)return fetch(evt.request).then(function (response) {console.log('fetch获取到的response:', response)// 必须是有效请求,必须是同源响应,第三方的请求,因为不可控,最好不要缓存if (!response || response.status !== 200 || response.type !== 'basic') {caches.open(version).then(function (cache) {cache.put(evt.request, response)})}return response;})}).catch(function (err) {console.error('fetch 接口错误', err)throw err}))
})

serviceWorker 服务器与浏览器之间的代理相关推荐

  1. Burpsuite工具与浏览器之间设置代理、安装证书

    在使用DVWA的漏洞列表时,需要使用Burpsuite进行抓包,改包等一系列操作: 所以,在进行DVWA漏洞列表中的实验之前,首先需要设置浏览器和Burpsuite的代理,以及安装证书: 1. 在浏览 ...

  2. pythonweb静态服务器_python实现外部静态服务器,浏览器通过HTTP与之通信2

    python实现外部静态服务器,浏览器通过HTTP与之通信2 发布时间:2019-07-10 14:29, 浏览次数:117 , 标签: python HTTP 因为网络间通信是基于TCP协议传输数据 ...

  3. python实现外部静态服务器,浏览器通过HTTP与之通信1

        因为网络间通信是基于TCP协议传输数据的,而服务器与浏览器之间通信是基于HTTP协议的,那么下面基于python实现一个tcp服务器,浏览器可以基于http协议进行发送请求和解析.展示浏览器返 ...

  4. python实现外部静态服务器,浏览器通过HTTP与之通信2

            因为网络间通信是基于TCP协议传输数据的,而服务器与浏览器之间通信是基于HTTP协议的,那么下面基于python实现一个tcp服务器,浏览器可以基于http协议进行发送请求和解析.浏览 ...

  5. [nginx代理配置][nginx proxy_pass][nginx从一台服务器代理到另外一台服务器,浏览器地址不改变]

    1.两台服务器 (1). 172.16.0.90 apache服务器 浏览器访问如下: 服务器里查看如下: 2). 172.16.0.58 nginx服务器 下有download目录 浏览器效果如下: ...

  6. PRX 通过LSP实现浏览器Socks5/Tcp代理(从发送数据上着手)

    本文阐述针对市面上主流的浏览器 实现基于Socks5协议Tcp代理部分原理 它是浏览器翻墙的一种方法 这只是在LSP实现方式中一种类别 它具备很多不同方式 但在本文中不在累赘:此方法适应"C ...

  7. 十分钟用Windows服务器简单搭建DHCP中继代理!!

                         十分钟用Windows服务器简单搭建DHCP中继代理!! 一.什么是中继代理? 大家都知道DHCP分配地址都需要用到IP广播,但是广播是不能在两个网段之间进行 ...

  8. 用浏览器访问云服务器文件,浏览器访问云服务器文件

    浏览器访问云服务器文件 内容精选 换一换 安装传输工具在本地主机和Windows云服务器上分别安装数据传输工具,将文件上传到云服务器.例如QQ.exe.在本地主机和Windows云服务器上分别安装数据 ...

  9. 项目中所了解的一些浏览器之间的差异

    各主流浏览器的区别各主流浏览器的区别 http://www.cnblogs.com/lhb25/archive/2013/06/05/html5-and-css3-2013.html 一. Tride ...

  10. 网页从web服务器受到的威胁,网页从web服务器方面浏览器方面受到的威胁主要来自哪里...

    网页从web服务器方面浏览器方面受到的威胁主要来自哪里 关注:117  答案:2  信息版本:手机版 解决时间 2019-01-14 09:04 情歌越听越心酸 2019-01-13 09:14 网页 ...

最新文章

  1. JavaScript的Array一些非常规玩法
  2. 叶际微生物定殖模型研究进展
  3. 他花了一个月,使用MicroPython将自己装进OLED里面
  4. Python yield 用法
  5. 答“我们的团队项目是否有大泥球?”
  6. 重装mysql遇到的问题
  7. java 示例_功能Java示例 第4部分–首选不变性
  8. css的再深入7(更新中···)
  9. 赚大钱必备 怎样成为赚钱高手(图)
  10. Linux的实际操作:Linux的分区
  11. Asp.Net中备份还原SqlServer数据库
  12. LeetCode 718最长重复子数组
  13. JAVA---数组从小到大排序方法
  14. 鲲鹏920的服务器芯片,鲲鹏920芯片是什么芯片
  15. 前后端分离详解(转发)
  16. python空气质量指数计算_Python入门案例(八):空气质量指数(AQI)计算
  17. vos3000如何检查落地网关配置正常,路由分析
  18. 多元函数链导法则的理解
  19. 软件工程导论第六版 第五章 总体设计知识点总结
  20. SOCKS代理的定义

热门文章

  1. Python 爬取蜂鸟网的照片
  2. 计算机病毒有熊猫病毒,世界最厉害的电脑病毒排名 熊猫烧香病毒最使人讨厌...
  3. 【JAVA基础速过】第3章 数组+Arrays工具类的使用
  4. 用计算机语言写结婚祝福语,[结婚电子显示屏祝福语]电子显示屏结婚贺词
  5. 123456789中间任意加+或-结果等于100
  6. GoLang之defer、panic、recover
  7. Ps“反转负冲”人像处理一例
  8. 豆瓣电影数据分析案例
  9. HTML中温度符号的输入
  10. 实例讲解EasyLanguage入门