self.addEventListener('install', (event) => { console.log('install event:', event) // The promise that skipWaiting() returns can be safely ignored. self.skipWaiting() // Perform any other actions required for your // service worker to install, potentially inside // of event.waitUntil(); }) self.addEventListener('activate', (event) => { event.waitUntil( clients.claim(), // Привязка нового сервис-воркера к текущим клиентам ) }) self.addEventListener('push', (event) => { const data = event.data.json() console.log('Push событие получено:', data.type) // Отображение уведомления if (data.type === 'notification') { event.waitUntil( self.registration .showNotification(data.notification.title, data.notification.options) .then(() => { console.log('Notification создан', data.notification.options.tag) }) .catch((error) => { console.error('Notification ошибка создания', error) }), ) } else if (data.type === 'cancelNotification') { event.waitUntil( self.registration .getNotifications({ tag: data.notification.options.tag }) .then((notifications) => { notifications.forEach((notification) => { if ( notification.tag === data.notification.options.tag || notification.data.payload.tag === data.notification.options.data.payload.tag // удалить, если notification.tag поддерживают все ) { notification.close() console.log('Notification удален') } }) }), ) } }) self.addEventListener('notificationclose', function (event) { const dismissedNotification = event.notification console.log('dismissedNotification', dismissedNotification) }) self.addEventListener('notificationclick', (event) => { console.log('click to notification', event.notification) event.notification.close() // const urlToOpen = new URL(event.notification.data.url, self.location.origin).href if (!event.notification.data.url) { console.log('no urlToOpen') return } function getNotificationUrl(urlToOpen) { return urlToOpen // return fetch(urlToOpen, { // redirect: 'manual', // method: 'HEAD', // cache: 'no-cache', // }) // .then((response) => { // console.log('response.url', response.url) // console.log('response.type', response.url) // if (response && response.type === 'opaqueredirect') { // const location = response.headers.get('location') // console.log('headers location', location) // return location // } // return response.url // }) // .catch((error) => { // console.debug('erro in getNotificationUrl', error) // return urlToOpen // }) } // Открытие URL из данных уведомления event.waitUntil( Promise.all([ getNotificationUrl(event.notification.data.url), clients.matchAll({ type: 'window', includeUncontrolled: true }), ]) .then(([urlToOpen, clientList]) => { for (const client of clientList) { console.log('client.url', client.url) if (client.url === urlToOpen && 'focus' in client) { console.log('focus') return Promise.all([ client.focus(), client.postMessage({ type: 'notificationClick', tag: event.notification.tag, payload: event.notification.payload, matchUrl: true, }), ]) } } if (clients.openWindow) { console.log('open new window', urlToOpen) return clients.openWindow(urlToOpen).then((client) => { if (!client) { console.log('new window not opened') for (const client of clientList) { return client.navigate(urlToOpen) // return client.postMessage({ // type: 'notificationClick', // url: urlToOpen, // tag: event.notification.tag, // payload: event.notification.payload, // matchUrl: false, // msg: 'new window not opened', // }) } } }) } else { console.log('clients.openWindow not available') for (const client of clientList) { return client.navigate(urlToOpen) // return client.postMessage({ // type: 'notificationClick', // url: urlToOpen, // tag: event.notification.tag, // payload: event.notification.payload, // matchUrl: false, // msg: 'clients.openWindow not available', // }) } } }) .catch((error) => { console.error(error) }), ) })