service worker
Posted yiyi17
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了service worker相关的知识,希望对你有一定的参考价值。
这是配置的sw.js
已测试,是OK的.
‘use strict‘; const version = ‘v2‘; const __DEVELOPMENT__ = false; const __DEBUG__ = true; const offlineResources = [ ‘./tt.html‘, ‘./images/1.png‘, // ‘/imgerror.jpg‘, // ‘/favicon.ico‘ ]; const ignoreCache = [ /https?:\/\/hm.baidu.com\//, /https?:\/\/www.google-analytics.com\//, /http?:\/\/resource.haorooms.com\//, /https?:\/\/www.haorooms.com\/admin/, /https?:\/\/github.com\//, // /https?:\/\/z4.cnzz.com\//, ]; // 慎重使用全局可变变量,因为 serviceWork 不可控的停止和重启,会导致它们的取值在后续读取时无法预测 let port; /** * common function */ function developmentMode() return __DEVELOPMENT__ || __DEBUG__; function cacheKey() return [version, ...arguments].join(‘:‘); function log() if (developmentMode()) console.log("SW:", ...arguments); // 不需要缓存的请求 function shouldAlwaysFetch(request) return __DEVELOPMENT__ || request.method !== ‘GET‘ || ignoreCache.some(regex => request.url.match(regex)); // 缓存 html 页面 function shouldFetchAndCache(request) return (/text\/html/i).test(request.headers.get(‘Accept‘)); // 发送 Notification 通知 function sendNotify(title, options, event) if (Notification.permission !== ‘granted‘) log(‘Not granted Notification permission.‘); // 无授权时,向来源页面申请授权 if (port && port.postMessage) port.postMessage( type: ‘applyNotify‘, info: title, options ); return; const notificationPromise = self.registration.showNotification(title || ‘Hi:‘, Object.assign( body: ‘这是一个通知示例‘, icon: ‘./images/1.png‘, requireInteraction: true, // tag: ‘push‘ , options)); return event && event.waitUntil(notificationPromise); /** * onClickNotify */ function onClickNotify(event) event.notification.close(); const url = "https://www.xueersi.com"; event.waitUntil( self.clients.matchAll( type: "window" ) .then(() => if (self.clients.openWindow) return self.clients.openWindow(url); ) ); /** * Install 安装 */ function onInstall(event) log(‘install event in progress.‘); event.waitUntil( caches.open(cacheKey(‘offline‘)) .then(cache => cache.addAll(offlineResources)) .then(() => log(‘installation complete! version: ‘ + version)) .then(() => self.skipWaiting()) ); /** * Fetch */ // 当网络离线或请求发生了错误,使用离线资源替代 request 请求 function offlineResponse(request) log(‘(offline)‘, request.method, request.url); if (request.url.match(/\.(jpg|png|gif|svg|jpeg)(\?.*)?$/)) return caches.match(‘./imgerror.jpg‘); else return caches.match(‘./offline.html‘); // 从缓存读取或使用离线资源替代 function cachedOrOffline(request) return caches .match(request) .then((response) => response || offlineResponse(request)); // 从网络请求,并将请求成功的资源缓存 function networkedAndCache(request) return fetch(request) .then(response => const copy = response.clone(); caches.open(cacheKey(‘resources‘)) .then(cache => cache.put(request, copy); ); log("(network: cache write)", request.method, request.url); return response; ); // 优先从 cache 读取,读取失败则从网络请求并缓存。网络请求也失败,则使用离线资源替代 function cachedOrNetworked(request) return caches.match(request) .then((response) => log(response ? ‘(cached)‘ : ‘(network: cache miss)‘, request.method, request.url); return response || networkedAndCache(request) .catch(() => offlineResponse(request)); ); // 优先从网络请求,失败则使用离线资源替代 function networkedOrOffline(request) return fetch(request) .then(response => log(‘(network)‘, request.method, request.url); return response; ) .catch(() => offlineResponse(request)); function onFetch(event) const request = event.request; // 应当永远从网络请求的资源 // 如果请求失败,则使用离线资源替代 if (shouldAlwaysFetch(request)) log(‘AlwaysFetch request: ‘, event.request.url); event.respondWith(networkedOrOffline(request)); return; // 应当从网络请求并缓存的资源 // 如果请求失败,则尝试从缓存读取,读取失败则使用离线资源替代 if (shouldFetchAndCache(request)) event.respondWith( networkedAndCache(request).catch(() => cachedOrOffline(request)) ); return; event.respondWith(cachedOrNetworked(request)); /** * Activate */ function removeOldCache() return caches .keys() .then(keys => Promise.all( // 等待所有旧的资源都清理完成 keys .filter(key => !key.startsWith(version)) // 过滤不需要删除的资源 .map(key => caches.delete(key)) // 删除旧版本资源,返回为 Promise 对象 ) ) .then(() => log(‘removeOldCache completed.‘); ); function onActivate(event) log(‘activate event in progress.‘); event.waitUntil(Promise.all([ // 更新客户端 self.clients.claim(), removeOldCache() ])) /** * onPush */ function onPush(event) log(‘onPush ‘, event); sendNotify(‘Hi:‘, body: `发生了一次 Push 同步事件 ~` , event); /** * onSync */ function onSync(event) log(‘onSync‘, event); sendNotify(‘Hi:‘, body: `发生了一次 Sync 同步事件 ~` , event); /** * onMessage */ function onMessage(event) log(‘onMessage‘, event); if (event.ports) port = event.ports[0]; if (!event.data) return; // 如果是要求一条通知,则发送 if (event.data.type === ‘notify‘) const title, options = event.data.info || ; sendNotify(title, options, event); log("Hello from ServiceWorker land!", version); self.addEventListener(‘install‘, onInstall); self.addEventListener(‘fetch‘, onFetch); self.addEventListener("activate", onActivate); self.addEventListener("push", onPush); self.addEventListener("sync", onSync); self.addEventListener(‘message‘, onMessage); self.addEventListener("notificationclick", onClickNotify);
以上是关于service worker的主要内容,如果未能解决你的问题,请参考以下文章