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.baidu.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);
你要觉得这篇文章比较好,记得点推荐!

浙公网安备 33010602011771号