Service Worker обновляется, но старый файл все еще кэшируется - PullRequest
1 голос
/ 14 января 2020

Когда я обновляю сервисного работника, я закрываю и снова открываю страницу и получаю журнал консоли, в котором новый сервисный работник установлен и активирован, а старый кеш удален. Однако файлы, перечисленные для добавления в кэш, не извлекаются с сервера снова, они являются устаревшими версиями часов go. Нет способа заставить его обновить файлы без очистки хранилища в Chrome dev tools.

Как я могу заставить моего сервисного работника заполнять свой кеш файлами fre sh при установке новой версии?

Например, «таблица стилей. css» остается старой версией, когда работник службы обновляет:

let cacheName = "abc_web_v1_15";

self.addEventListener('install', (event) => {
    console.log('[Service Worker] Install');
    event.waitUntil(
        caches.open(cacheName).then(function (cache) {
            return cache.addAll([
                "/".
                "/stylesheet.css",
                ...
            ]);
        })
    );
});
self.addEventListener('fetch', (e) => {
    e.respondWith(
        caches.match(e.request).then(function (r) {
            console.log('[Service Worker] Fetching resource: ' + cacheName + ' ' + e.request.url);
            if (r) {
                console.log(cacheName + ' returning cached  ' + e.request);
                return r;
            } else {
                console.log(cacheName + ' returning fetched  ' + e.request);
                return fetch(e.request);
            }
        })
    )
});

self.addEventListener('activate', (e) => {
    console.log('[Service Worker] Activate');
    e.waitUntil(
        caches.keys().then((keyList) => {
            return Promise.all(keyList.map((key) => {
                if (cacheName.indexOf(key) === -1) {
                    console.log(`[Service Worker] Removing Cached Files from Cach-${key}`);
                    return caches.delete(key);
                }
            }));
        })
    );
});

Ответы [ 2 ]

1 голос
/ 14 января 2020

Проблема очень проста: когда ваш Service Worker запрашивает «новые» файлы, этот запрос fetch проходит через обычный HTTP-кеш браузера. Если ресурс найден там, браузер автоматически возвращает его и не go в сеть.

Если вы посмотрите на этот фрагмент из своего кода:

return cache.addAll([
                "/".
                "/stylesheet.css",
                ...
            ]);

, вы увидите что имя вашей таблицы стилей всегда одинаково, независимо от содержимого. Другими словами, когда ваша таблица стилей обновляется, имя файла остается прежним. По этой причине файл уже находится в HTTP-кэше браузера, и, таким образом, SW получает его, когда запрашивает его.

Вам следует создать версию своих файлов. Обычно используется ха sh содержимого файла. С именами ha sh вы получите имена, подобные stylesheet.iudfirio132.css, и это имя меняется каждый раз, когда файл меняет хотя бы один символ. Таким образом, новая версия вашего приложения всегда использует ресурсы с разными именами. Вы также должны иметь инструменты сборки, такие как предварительное кэширование Workbox, для обновления списка ресурсов в файле Service Worker, чтобы вам не приходилось делать это вручную. Подробнее: https://developers.google.com/web/tools/workbox/modules/workbox-precaching

Чтобы полностью уточнить тему asp здесь, я рекомендую вам прочитать эту статью в блоге "Кэширование лучших практик и макс-эйдж готч" "https://jakearchibald.com/2016/caching-best-practices/

0 голосов
/ 14 января 2020

Я держу этот самоуничтожающийся сервисный работник под рукой, когда мне нужно очистить все старые кэши сервисных работников и сервисных работников.

Я считаю это действительно полезным инструментом.

self.addEventListener('install', event => self.skipWaiting());

self.addEventListener('activate', event => {

  // Delete all Service Worker Caches
  caches.keys().then(cacheNames => {for (let name of cacheNames) {caches.delete(name);}});

  // Unregister all Service Workers
  self.registration.unregister()

    .then(() => self.clients.matchAll())

    .then((clients) => clients.forEach(client => client.navigate(client.url)))

});

Дополнительная литература:

...