上一篇文章《service worker简单配置》已经展现出一个方案用来缓存文件,思路是将需要缓存的文件以白名单的形式枚举出来,这篇文章介绍的方法则是反向的思路,黑名单的方式,将不需要缓存的文件域枚举出来,一般都是第三方的库文件为主。
首先一样是在页面注册serviceworker:
if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js'); }
这里注册在的文件名叫sw.js,并且是在网站根目录,所有的页面都是这样注册,然后是sw.js的详细配置:
'use strict'; const version = 'v20180608'; const __DEVELOPMENT__ = false; const __DEBUG__ = false; const offlineResources = [ //离线断网的时候提供友好界面 '/', '/offline.html', '/offline.svg' ]; const ignoreFetch = [ //这里是需要忽略的第三方的域名 /chrome-extension:///, // 建议加上忽略chrome插件的协议 /https?://cdn.bootcss.com//, /https?://zz.bdstatic.com//, /https?://s.360.cn//, /https?://s.ssl.qhres.com//, /https?://hm.baidu.com//, /https?://s19.cnzz.com//, /https?://sp0.baidu.com//, /https?://tag.baidu.com//, /https?://msite.baidu.com//, /https?://s.bdstatic.com//, /https?://timg01.bdimg.com//, ]; ////////// // Install ////////// function onInstall(event) { log('install event in progress.'); event.waitUntil(updateStaticCache()); } function updateStaticCache() { return caches .open(cacheKey('offline')) .then((cache) => { return cache.addAll(offlineResources); }) .then(() => { log('installation complete!'); }); } //////// // Fetch //////// function onFetch(event) { const request = event.request; if (shouldAlwaysFetch(request)) { event.respondWith(networkedOrOffline(request)); return; } if (shouldFetchAndCache(request)) { event.respondWith(networkedOrCached(request)); return; } event.respondWith(cachedOrNetworked(request)); } function networkedOrCached(request) { return networkedAndCache(request) .catch(() => { return cachedOrOffline(request) }); } // Stash response in cache as side-effect of network request function networkedAndCache(request) { return fetch(request) .then((response) => { var copy = response.clone(); caches.open(cacheKey('resources')) .then((cache) => { cache.put(request, copy); }); log("(network: cache write)", request.method, request.url); return response; }); } function cachedOrNetworked(request) { return caches.match(request) .then((response) => { log(response ? '(cached)' : '(network: cache miss)', request.method, request.url); return response || networkedAndCache(request) .catch(() => { return offlineResponse(request) }); }); } function networkedOrOffline(request) { return fetch(request) .then((response) => { log('(network)', request.method, request.url); return response; }) .catch(() => { return offlineResponse(request); }); } function cachedOrOffline(request) { return caches .match(request) .then((response) => { return response || offlineResponse(request); }); } function offlineResponse(request) { log('(offline)', request.method, request.url); if (request.url.match(/.(jpg|png|gif|svg|jpeg)(?.*)?$/)) { return caches.match('/offline.svg'); } else { return caches.match('/offline.html'); } } /////////// // Activate /////////// function onActivate(event) { log('activate event in progress.'); event.waitUntil(removeOldCache()); } function removeOldCache() { return caches .keys() .then((keys) => { return Promise.all( // We return a promise that settles when all outdated caches are deleted. keys .filter((key) => { return !key.startsWith(version); // Filter by keys that don't start with the latest version prefix. }) .map((key) => { return caches.delete(key); // Return a promise that's fulfilled when each outdated cache is deleted. }) ); }) .then(() => { log('removeOldCache completed.'); }); } function cacheKey() { return [version, ...arguments].join(':'); } function log() { if (developmentMode()) { console.log("SW:", ...arguments); } } function shouldAlwaysFetch(request) { return __DEVELOPMENT__ || request.method !== 'GET' || ignoreFetch.some(regex => request.url.match(regex)); } function shouldFetchAndCache(request) { return ~request.headers.get('Accept').indexOf('text/html'); } function developmentMode() { return __DEVELOPMENT__ || __DEBUG__; } log("Hello from ServiceWorker land!", version); self.addEventListener('install', onInstall); self.addEventListener('fetch', onFetch); self.addEventListener("activate", onActivate);
PS.这里有相关的前端页面优化的一些配置