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
關注個人微信公衆號,更多優質文章定時推送