// public/service-worker.js /** * Service Worker for Browser Notifications * 主要功能:支持浏览器通知的稳定运行 */ const CACHE_NAME = 'valuefrontier-v1'; // Service Worker 安装事件 self.addEventListener('install', (event) => { console.log('[Service Worker] Installing...'); // 跳过等待,立即激活 self.skipWaiting(); }); // Service Worker 激活事件 self.addEventListener('activate', (event) => { console.log('[Service Worker] Activating...'); // 立即接管所有页面 event.waitUntil(self.clients.claim()); }); // 通知点击事件 self.addEventListener('notificationclick', (event) => { console.log('[Service Worker] Notification clicked:', event.notification.tag); event.notification.close(); // 获取通知数据中的链接 const urlToOpen = event.notification.data?.link; if (urlToOpen) { event.waitUntil( clients.matchAll({ type: 'window', includeUncontrolled: true }) .then((windowClients) => { // 查找是否已有打开的窗口 for (let client of windowClients) { if (client.url.includes(window.location.origin) && 'focus' in client) { // 聚焦现有窗口并导航到目标页面 return client.focus().then(client => { return client.navigate(urlToOpen); }); } } // 如果没有打开的窗口,打开新窗口 if (clients.openWindow) { return clients.openWindow(urlToOpen); } }) ); } }); // 通知关闭事件 self.addEventListener('notificationclose', (event) => { console.log('[Service Worker] Notification closed:', event.notification.tag); }); // Fetch 事件 - 基础的网络优先策略 self.addEventListener('fetch', (event) => { // 对于通知相关的资源,使用网络优先策略 event.respondWith( fetch(event.request) .catch(() => { // 网络失败时,尝试从缓存获取 return caches.match(event.request); }) ); }); // 推送消息事件(预留,用于未来的 Push API 集成) self.addEventListener('push', (event) => { console.log('[Service Worker] Push message received:', event); if (event.data) { const data = event.data.json(); const options = { body: data.body || '您有新消息', icon: data.icon || '/favicon.png', badge: '/favicon.png', data: data.data || {}, requireInteraction: data.requireInteraction || false, tag: data.tag || `notification_${Date.now()}`, }; event.waitUntil( self.registration.showNotification(data.title || '价值前沿', options) ); } }); console.log('[Service Worker] Loaded successfully');