pwa-之service worker 離線文件處理

pwa-之service worker 基本概念
pwa-之service worker 離線文件處理css

本章包含如下知識點html

  • 顯示離線頁面
  • 加載離線圖片
  • 加載離線css
  • 多個fetch處理事件調用

簡介

網站圖片因爲不肯定的緣由,可能沒法訪問,這給用戶一個錯覺,就是你的網站出了問題segmentfault

其餘諸如css,js文件都是網站必不可少的資源,本章咱們來學些如何加載這些資源瀏覽器

首先讓咱們來看看一個離線頁面緩存

顯示離線頁面

  1. 建立一個html頁面
<!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>
  1. 建立一個service-worker.js文件
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);
}
  1. 建立offline.html頁面
<!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>
  1. 建立offline.svg文件
<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>
  1. 打開index.html頁面。

image

  1. 勾上network->offline:刷新頁面,顯示如圖

image

實現原理

image

使用cache Api,預先緩存offline.html和offline.svg。當網絡不通時,html請求走到cache方法裏面去,而後響應的是緩存好的offline.html。offline.html又請求已經緩存好的offline.svg。因此正常顯示。服務器

加載離線圖片

  1. 建立index.html
<!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>
  1. 建立index.js
'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';
}
  1. 建立service-worker.js
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。這樣子咱們的頁面緩存不會生效。

加載離線css

  1. 建立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>
  1. 建立service-worker.js
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));
  }
});
  1. 建立style-1.css
body {
    background-color: lightgreen;
}
  1. 建立style-2.css
body {
    background-color: red;
}

一樣訪問html能夠看到綠色的背景,offline以後顯示的紅色的背景。網絡

必定要訪問 index.html啊,否則不會成功

多個fetch事件調用

fetch事件和js其餘事件同樣都是能夠註冊屢次的。app

  1. 建立index.html
<!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>
  1. 建立service-worker.js
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

image

而後訪問/cook/,是/cook/不是/cook

image

訪問/cook/book

image

關注個人微信公衆號,更多優質文章定時推送
clipboard.png

相關文章
相關標籤/搜索