2016-05-09 3 views
6

У меня есть рабочий, установленный на моем веб-сайте, все работает нормально, за исключением случаев, когда я нажимаю обновление для кэшированных файлов; они остаются пойманной навсегда, и я, кажется, не в состоянии сделать недействительным кэш, если я не отписываться работника из `хром: // serviceworker-Internals/Сервисные работники, не обновляющие

const STATIC_CACHE_NAME = 'static-cache-v1'; 
const APP_CACHE_NAME = 'app-cache-#VERSION'; 

const CACHE_APP = [ 
    '/', 
    '/app/app.js' 
] 
const CACHE_STATIC = [ 
    'https://fonts.googleapis.com/css?family=Roboto:400,300,500,700', 
    'https://cdnjs.cloudflare.com/ajax/libs/normalize/4.1.1/normalize.min.css' 
] 

self.addEventListener('install',function(e){ 
    e.waitUntil(
     Promise.all([caches.open(STATIC_CACHE_NAME),caches.open(APP_CACHE_NAME)]).then(function(storage){ 
      var static_cache = storage[0]; 
      var app_cache = storage[1]; 
      return Promise.all([static_cache.addAll(CACHE_STATIC),app_cache.addAll(CACHE_APP)]); 
     }) 
    ); 
}); 

self.addEventListener('activate', function(e) { 
    e.waitUntil(
     caches.keys().then(function(cacheNames) { 
      return Promise.all(
       cacheNames.map(function(cacheName) { 
        if (cacheName !== APP_CACHE_NAME && cacheName !== STATIC_CACHE_NAME) { 
         console.log('deleting',cacheName); 
         return caches.delete(cacheName); 
        } 
       }) 
      ); 
     }) 
    ); 
}); 

self.addEventListener('fetch',function(e){ 
    const url = new URL(e.request.url); 
    if (url.hostname === 'static.mysite.co' || url.hostname === 'cdnjs.cloudflare.com' || url.hostname === 'fonts.googleapis.com'){ 
     e.respondWith(
      caches.match(e.request).then(function(response){ 
       if (response) { 
        return response; 
       } 
       var fetchRequest = e.request.clone(); 

       return fetch(fetchRequest).then(function(response) { 
        if (!response || response.status !== 200 || response.type !== 'basic') { 
         return response; 
        } 
        var responseToCache = response.clone(); 
        caches.open(STATIC_CACHE_NAME).then(function(cache) { 
         cache.put(e.request, responseToCache); 
        }); 
        return response; 
       }); 
      }) 
     ); 
    } else if (CACHE_APP.indexOf(url.pathname) !== -1){ 
     e.respondWith(caches.match(e.request)); 
    } 
}); 

где #Version является версия, которая прилагается к имени кэша во время компиляции; обратите внимание, что STATIC_CACHE_NAME никогда не изменяется, так как файлы считаются статическими навсегда.

Также поведение ошибочно, я проверяю функцию удаления (часть, в которой он регистрируется), и он продолжает вести журнал об удалении кешей, которые уже были удалены (предположительно). когда я запускаю caches.keys().then(function(k){console.log(k)}) Я получаю целую кучу старых кешей, которые нужно было удалить.

ответ

6

После поиска в Интернете и просмотра некоторых видеороликов по udacity я обнаружил, что предполагаемое поведение работника должно оставаться до тех пор, пока контролируемая страница не будет закрыта и снова открыта, когда новый сервисный работник может взять под контроль.

Решение состояло в том, чтобы заставить его взять под контроль на основе https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerGlobalScope/skipWaiting следующее решение проблемы, даже если требуется 2 перезагрузки, чтобы новый работник отражал изменения (что имеет смысл, поскольку приложение загружается до нового рабочий заменяет предыдущий).

self.addEventListener('install',function(e){ 
    e.waitUntil(
     Promise.all([caches.open(STATIC_CACHE_NAME),caches.open(APP_CACHE_NAME),self.skipWaiting()]).then(function(storage){ 
      var static_cache = storage[0]; 
      var app_cache = storage[1]; 
      return Promise.all([static_cache.addAll(CACHE_STATIC),app_cache.addAll(CACHE_APP)]); 
     }) 
    ); 
}); 

self.addEventListener('activate', function(e) { 
    e.waitUntil(
     Promise.all([ 
      self.clients.claim(), 
      caches.keys().then(function(cacheNames) { 
       return Promise.all(
        cacheNames.map(function(cacheName) { 
         if (cacheName !== APP_CACHE_NAME && cacheName !== STATIC_CACHE_NAME) { 
          console.log('deleting',cacheName); 
          return caches.delete(cacheName); 
         } 
        }) 
       ); 
      }) 
     ]) 
    ); 
}); 
+2

Помните, что вы можете использовать 'self.skipWaiting()' вне обещания. – Salva

Смежные вопросы