pwa-之service worker 离线文件处理

pwa-之service worker 基本概念
pwa-之service worker 离线文件处理

本章包含以下知识点

  • 显示离线页面
  • 加载离线图片
  • 加载离线css
  • 多个fetch处理事件调用

简介

网站图片由于不确定的原因,可能无法访问,这给用户一个错觉,就是你的网站出了问题

其他诸如css,js文件都是网站必不可少的资源,本章我们来学些如何加载这些资源

首先让我们来看看一个离线页面

显示离线页面

  1. 创建一个html页面



  
  Custom Offline Page


  

Registration status:

  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页面


 
  
  Offline
 
 
   

Whoops! Your internet connection is not working.

Please check your network connection and try again.

  1. 创建offline.svg文件

  

  1. 打开index.html页面。

  1. 勾上network->offline:刷新页面,显示如图

实现原理

使用cache Api,预先缓存offline.html和offline.svg。当网络不通时,html请求走到cache方法里面去,然后响应的是缓存好的offline.html。offline.html又请求已经缓存好的offline.svg。所以正常显示。

加载离线图片

  1. 创建index.html



  
  Offline Images


  

Registration status:

logo
  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



  
  Offline CSS
  
  


  

Registration status:

  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其他事件一样都是可以注册多次的。

  1. 创建index.html



  
  Mutiple Fetch


  

Registration status:

  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);
});

浏览器里面访问

然后访问/cook/,是/cook/不是/cook

访问/cook/book

关注我的微信公众号,更多优质文章定时推送

你可能感兴趣的:(pwa,service-worker,javascript,fetch,缓存)