NoteJS/public/sw.js
Fovway 091fc6cc1e Обновлены мета-теги и улучшена функциональность PWA
- Оптимизированы мета-теги в index.html и test-pwa.html для лучшей поддержки PWA.
- Улучшена структура кода с использованием многострочных атрибутов для мета-тегов.
- Обновлен сервисный работник для более эффективного кэширования и обработки запросов.
- Добавлены новые функции в pwa.js для управления установкой и обновлением PWA.
2025-10-20 12:29:43 +07:00

236 lines
7.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Service Worker для NoteJS
const APP_VERSION = "1.0.5";
const CACHE_NAME = `notejs-v${APP_VERSION}`;
const STATIC_CACHE_NAME = `notejs-static-v${APP_VERSION}`;
// Файлы для кэширования при установке (только изображения, иконки, логотипы)
// Манифест убран - не нужен для офлайн работы
const STATIC_FILES = [
"/icons/icon-72x72.png",
"/icons/icon-96x96.png",
"/icons/icon-128x128.png",
"/icons/icon-144x144.png",
"/icons/icon-152x152.png",
"/icons/icon-192x192.png",
"/icons/icon-384x384.png",
"/icons/icon-512x512.png",
"/icons/icon-32x32.png",
"/icons/icon-16x16.png",
"/icons/icon-48x48.png",
"/icon.svg",
"/logo.svg",
];
// Установка Service Worker
self.addEventListener("install", (event) => {
console.log("[SW] Установка Service Worker");
event.waitUntil(
caches
.open(STATIC_CACHE_NAME)
.then((cache) => {
console.log("[SW] Кэширование статических файлов");
return cache.addAll(STATIC_FILES);
})
.then(() => {
console.log("[SW] Статические файлы закэшированы");
return self.skipWaiting();
})
.catch((error) => {
console.error("[SW] Ошибка при кэшировании статических файлов:", error);
// Продолжаем работу даже если кэширование не удалось
return self.skipWaiting();
})
);
});
// Активация Service Worker
self.addEventListener("activate", (event) => {
console.log("[SW] Активация Service Worker");
event.waitUntil(
caches
.keys()
.then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
// Удаляем старые кэши
if (cacheName !== STATIC_CACHE_NAME) {
console.log("[SW] Удаление старого кэша:", cacheName);
return caches.delete(cacheName);
}
})
);
})
.then(() => {
console.log("[SW] Service Worker активирован");
return self.clients.claim();
})
);
});
// Перехват запросов
self.addEventListener("fetch", (event) => {
const { request } = event;
const url = new URL(request.url);
// Пропускаем запросы к API и загрузкам
if (
url.pathname.startsWith("/api/") ||
url.pathname.startsWith("/uploads/") ||
url.pathname.startsWith("/database/")
) {
return;
}
// Пропускаем запросы к внешним ресурсам
if (url.origin !== location.origin) {
return;
}
// Пропускаем HTML файлы и CSS - не кэшируем их
if (
url.pathname.endsWith(".html") ||
url.pathname.endsWith(".css") ||
url.pathname === "/" ||
url.pathname === "/index.html" ||
url.pathname === "/login.html" ||
url.pathname === "/register.html" ||
url.pathname === "/notes.html" ||
url.pathname === "/profile.html"
) {
return;
}
// Обрабатываем только GET запросы для изображений, иконок и манифеста
if (request.method === "GET") {
event.respondWith(handleRequest(request));
}
});
async function handleRequest(request) {
try {
// Сначала пытаемся получить из кэша
const cachedResponse = await caches.match(request);
if (cachedResponse) {
console.log("[SW] Запрос из кэша:", request.url);
return cachedResponse;
}
// Если нет в кэше, загружаем из сети
console.log("[SW] Запрос к сети:", request.url);
const networkResponse = await fetch(request);
// Кэшируем только изображения и иконки (без манифеста)
if (networkResponse.ok && shouldCache(request)) {
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
console.error("[SW] Ошибка при обработке запроса:", error);
// НЕ предоставляем fallback - приложение работает только онлайн
throw error;
}
}
// Функция для определения, нужно ли кэшировать файл
function shouldCache(request) {
const url = new URL(request.url);
// Кэшируем только изображения, иконки и логотипы (без манифеста для офлайн работы)
return (
url.pathname.includes("/icons/") ||
url.pathname.endsWith(".png") ||
url.pathname.endsWith(".jpg") ||
url.pathname.endsWith(".jpeg") ||
url.pathname.endsWith(".gif") ||
url.pathname.endsWith(".webp") ||
url.pathname.endsWith(".svg")
);
}
// Обработка сообщений от основного потока
self.addEventListener("message", (event) => {
console.log("[SW] Получено сообщение:", event.data);
if (event.data && event.data.type === "SKIP_WAITING") {
self.skipWaiting();
}
if (event.data && event.data.type === "GET_VERSION") {
event.ports[0].postMessage({ version: CACHE_NAME });
}
if (event.data && event.data.type === "FORCE_UPDATE_CACHE") {
forceUpdateCache();
}
if (event.data && event.data.type === "CLEAR_ALL_CACHE") {
clearAllCache();
}
});
// Функция принудительного обновления кэша
async function forceUpdateCache() {
console.log("[SW] Принудительное обновление кэша...");
try {
// Удаляем все старые кэши
const cacheNames = await caches.keys();
await Promise.all(
cacheNames.map((cacheName) => {
console.log("[SW] Удаление кэша:", cacheName);
return caches.delete(cacheName);
})
);
// Создаем новый кэш с актуальной версией
const newCache = await caches.open(STATIC_CACHE_NAME);
await newCache.addAll(STATIC_FILES);
console.log("[SW] Кэш успешно обновлен до версии:", APP_VERSION);
// Уведомляем клиентов об обновлении
const clients = await self.clients.matchAll();
clients.forEach((client) => {
client.postMessage({
type: "CACHE_UPDATED",
version: APP_VERSION,
});
});
} catch (error) {
console.error("[SW] Ошибка при обновлении кэша:", error);
}
}
// Функция полной очистки кэша
async function clearAllCache() {
console.log("[SW] Полная очистка кэша...");
try {
const cacheNames = await caches.keys();
await Promise.all(
cacheNames.map((cacheName) => {
console.log("[SW] Удаление кэша:", cacheName);
return caches.delete(cacheName);
})
);
console.log("[SW] Весь кэш очищен");
// Уведомляем клиентов об очистке
const clients = await self.clients.matchAll();
clients.forEach((client) => {
client.postMessage({
type: "CACHE_CLEARED",
});
});
} catch (error) {
console.error("[SW] Ошибка при очистке кэша:", error);
}
}