Files
home/js/sw.js
hehh d19837edc2 feat(sw): 升级缓存版本并优化资源缓存策略
- 更新缓存名称从 v1.0.1 到 v1.1.0
- 移除部分图片资源路径配置
- 安装阶段增加 skipWaiting 强制更新
- 优化 fetch 拦截逻辑,区分 HTML、音频、图片及静态资源处理
- 增加对带版本号请求的特殊处理
- 激活阶段主动声明客户端控制权
- 改进缓存匹配忽略查询参数提高命中率
- 增强错误捕获避免中断服务工作线程运行
2025-11-25 20:05:26 +08:00

88 lines
2.5 KiB
JavaScript

const CACHE_NAME = 'honesty-home-v1.1.0';
const urlsToCache = [
'./index.html',
'./about.html',
'./css/style.css',
'./css/about.css',
'./css/artalk.css',
'./js/config.js',
'./js/about.js',
'./images/avatar.jpeg',
'./images/favicon.ico',
'./images/favicon.png',
'./images/logo.png',
'./images/INFJ.png'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
return cache.addAll(urlsToCache);
})
.catch(() => Promise.resolve())
);
self.skipWaiting();
});
self.addEventListener('fetch', event => {
if (event.request.method !== 'GET' || !event.request.url.startsWith(self.location.origin)) {
return;
}
const url = new URL(event.request.url);
const isHTML = event.request.mode === 'navigate' || url.pathname.endsWith('.html');
const isVersioned = url.search && /version=/.test(url.search);
const isAudio = url.pathname.endsWith('.mp3') || url.pathname.endsWith('.wav') || url.pathname.endsWith('.ogg');
const isImage = /\.(png|jpg|jpeg|gif|webp|svg)$/i.test(url.pathname);
const isStaticAsset = /\.(css|js|json)$/i.test(url.pathname);
if (isHTML || isVersioned || isAudio) {
event.respondWith(
fetch(event.request)
.then(resp => {
if (resp && resp.status === 200 && resp.type === 'basic' && !isAudio) {
const copy = resp.clone();
caches.open(CACHE_NAME).then(cache => cache.put(event.request, copy)).catch(() => {});
}
return resp;
})
.catch(() => {
return caches.match(event.request, { ignoreSearch: true })
.then(m => m || caches.match(event.request))
})
);
return;
}
event.respondWith(
caches.match(event.request, { ignoreSearch: true })
.then(cached => {
if (cached) return cached;
return fetch(event.request).then(resp => {
if (resp && resp.status === 200 && resp.type === 'basic' && (isImage || isStaticAsset)) {
const copy = resp.clone();
caches.open(CACHE_NAME).then(cache => cache.put(event.request, copy)).catch(() => {});
}
return resp;
});
})
);
});
self.addEventListener('activate', event => {
const cacheWhitelist = [CACHE_NAME];
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (!cacheWhitelist.includes(cacheName)) {
return caches.delete(cacheName);
}
})
);
})
);
self.clients.claim();
});