pwa-之service worker 基本概念
pwa-之service worker 离线文件处理css
本章包含如下知识点html
网站图片因为不肯定的缘由,可能没法访问,这给用户一个错觉,就是你的网站出了问题segmentfault
其余诸如css,js文件都是网站必不可少的资源,本章咱们来学些如何加载这些资源浏览器
首先让咱们来看看一个离线页面缓存
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Custom Offline Page</title> </head> <body> <p>Registration status: <strong id="status"></strong></p> <script> if ('serviceWorker' in navigator) { navigator.serviceWorker.register( 'service-worker.js', { scope: './' } ).then( function(serviceWorker) { document.getElementById('status').innerHTML = 'successful'; }).catch(function(error) { document.getElementById('status').innerHTML = error; }); } else { document.getElementById('status').innerHTML = 'unavailable'; } </script> </body> </html>
var version = 1; var currentCache = { offline: 'offline-cache' + version }; var offlineUrl = 'offline.html'; self.addEventListener('install', function(event) { event.waitUntil( caches.open(currentCache.offline).then(function(cache) { return cache.addAll([ 'offline.svg', offlineUrl ]); }) ); }); self.addEventListener('fetch', function(event) { // request.mode = navigate isn't supported in all browsers // so include a check for Accept: text/html header. if (event.request.mode === 'navigate' || (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html'))) { event.respondWith( fetch(createCacheBustedRequest(event.request.url)).catch(function(error) { // Return the offline page console.log('Fetch failed. Returning offline page instead.', error); return caches.match(offlineUrl); }) ); } else { // Respond with everything else if we can event.respondWith(caches.match(event.request) .then(function (response) { return response || fetch(event.request); }) ); } }); function createCacheBustedRequest(url) { var request = new Request(url, {cache: 'reload'} ); // See https://fetch.spec.whatwg.org/#concept-request-mode // This is not yet supported in Chrome as of M48, so we need to explicitly check to see // if the cache: 'reload' option had any effect. if ('cache' in request) { return request; } // If {cache: 'reload'} didn't have any effect, append a cache-busting URL parameter instead. var cacheBustingUrl = new URL(url, self.location.href); cacheBustingUrl.search += (cacheBustingUrl.search ? '&' : '') + 'cachebust=' + Date.now(); return new Request(cacheBustingUrl); }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Offline</title> </head> <body> <div style="text-align:center; margin-top:40px;"> <img src="offline.svg" width="80" height="80" /> <p>Whoops! Your internet connection is not working.</p> <p>Please check your network connection and try again.</p> <div> </body> </html>
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 25 25"> <path d="M16 0l-3 9h9l-1.866 2h-14.4L16 0zm2.267 13h-14.4L2 15h9l-3 9 10.267-11z" fill="#04b8b8"/> </svg>
使用cache Api,预先缓存offline.html和offline.svg。当网络不通时,html请求走到cache方法里面去,而后响应的是缓存好的offline.html。offline.html又请求已经缓存好的offline.svg。因此正常显示。服务器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Offline Images</title> </head> <body> <p>Registration status: <strong id="status"></strong></p> <img src="packt-logo.png" alt="logo"> <script src="index.js"></script> </body> </html>
'use strict'; if ('serviceWorker' in navigator) { navigator.serviceWorker.register( 'service-worker.js', { scope: './' } ).then( function(serviceWorker) { document.getElementById('status').innerHTML = 'successful'; }).catch(function(error) { document.getElementById('status').innerHTML = error; }); } else { document.getElementById('status').innerHTML = 'unavailable'; }
var version = 1; var cacheName = 'static-' + version; self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll([ 'index.html', 'packt-logo.png' ]); }) ); }); self.addEventListener('fetch', function(event) { event.respondWith(caches.match(event.request)); });
访问/Chapter%202/02/index.html,而后打开offline。页面仍然能够正常显示。微信
记住必定要加上index.html。大部分的服务器会把/
指向到index.html
。这样子咱们的页面缓存不会生效。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Offline CSS</title> <link rel="stylesheet" href="style-2.css"> <link rel="stylesheet" href="style-1.css"> </head> <body> <p>Registration status: <strong id="status"></strong></p> <script async> if ('serviceWorker' in navigator) { navigator.serviceWorker.register( 'service-worker.js', { scope: './' } ).then( function(serviceWorker) { document.getElementById('status').innerHTML = 'successful'; }).catch(function(error) { document.getElementById('status').innerHTML = error; }); } else { document.getElementById('status').innerHTML = 'unavailable'; } </script> </body> </html>
var version = 1; var cacheName = 'static-' + version; self.addEventListener('install', function(event) { event.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll([ 'index.html', 'style-2.css' ]); }) ); }); self.addEventListener('fetch', function(event) { if (/index/.test(event.request.url) || /style-2/.test(event.request.url)) { event.respondWith(caches.match(event.request)); } });
body { background-color: lightgreen; }
body { background-color: red; }
一样访问html能够看到绿色的背景,offline以后显示的红色的背景。网络
必定要访问
index.html
啊,否则不会成功
fetch事件和js其余事件同样都是能够注册屡次的。app
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Mutiple Fetch</title> </head> <body> <p>Registration status: <strong id="status"></strong></p> <script> if ('serviceWorker' in navigator) { navigator.serviceWorker.register( 'service-worker.js', { scope: './' } ).then( function(serviceWorker) { document.getElementById('status').innerHTML = 'successful'; }).catch(function(error) { document.getElementById('status').innerHTML = error; }); } else { document.getElementById('status').innerHTML = 'unavailable'; } </script> </body> </html>
var cookFetchHandler = function(event) { console.log('DEBUG: Inside the /cook handler.'); if (event.request.url.indexOf('/cook/') > 0) { event.respondWith(new Response('Fetch handler for /cook')); } }; var cookBookFetchHandler = function(event) { console.log('DEBUG: Inside the /cook/book handler.'); if (event.request.url.endsWith('/cook/book')) { event.respondWith(new Response('Fetch handler for /cook/book')); } }; var fetchHandlers = [cookBookFetchHandler, cookFetchHandler]; fetchHandlers.forEach(function(fetchHandler) { self.addEventListener('fetch', fetchHandler); });
浏览器里面访问async
而后访问/cook/
,是/cook/
不是/cook
访问/cook/book
关注个人微信公众号,更多优质文章定时推送