2016-09-07 1 views
3

Я использую сервис-службу на chrome для кэширования сетевых ответов. То, что я намереваюсь делать, когда клиент запрашивает ресурс:Работник службы Javascript: извлечение ресурса из кеша, но также его обновление

Проверить кеш - если он существует, вернитесь из кеша, а также отправьте запрос на сервер и кеш обновления, если файл отличается от кешированной версии. Если кэш не имеет его, отправьте запрос на него на сервер и затем кешируйте ответ.

Вот мой текущий код делает то же самое:

self.addEventListener('fetch', function (event) { 
    var requestURL = new URL(event.request.url); 
    var freshResource = fetch(event.request).then(function (response) { 
     if (response.ok && requestURL.origin === location.origin) { 
      // All good? Update the cache with the network response 
      caches.open(CACHE_NAME).then(function (cache) { 
       cache.put(event.request, response); 
      }); 
     } 
     // Return the clone as the response would be consumed while caching it 
     return response.clone(); 
    }); 
    var cachedResource = caches.open(CACHE_NAME).then(function (cache) { 
     return cache.match(event.request); 
    }); 
    event.respondWith(cachedResource.catch(function() { 
     return freshResource; 
    })); 
}); 

Этот код не работает, как он выдает ошибку:

The FetchEvent for url resulted in a network error response: an object that was not a Response was passed to respondWith().

Может кто-нибудь мне точку в правильном направлении?

+2

'catch' фактически возвращает объект Promise , вы можете захотеть привязать обработчик 'then' к' cachedResource' и вызвать 'replyWith' в пределах этого – thefourtheye

+0

@thefourtheye - Не имеете в виду, вызывайте' event.respondWith' внутри 'then' для' cache.match'? Это будет ошибка, так как выборка будет разрешена к моменту выполнения 'caches.open'. Я сделал изменение и запустил код, чтобы найти эту ошибку. – Awol

+0

@Awol: Как так? Предположительно, кеш открывается и соответствует быстрее, чем выборка? – Bergi

ответ

2

Хорошо, я возился с кодом после того, как люди указали предложения (спасибо за это) и нашли решение.

self.addEventListener('fetch', function (event) { 
    var requestURL = new URL(event.request.url); 
    var freshResource = fetch(event.request).then(function (response) { 
     var clonedResponse = response.clone(); 
     // Don't update the cache with error pages! 
     if (response.ok) { 
      // All good? Update the cache with the network response 
      caches.open(CACHE_NAME).then(function (cache) { 
       cache.put(event.request, clonedResponse); 
      }); 
     } 
     return response; 
    }); 
    var cachedResource = caches.open(CACHE_NAME).then(function (cache) { 
     return cache.match(event.request).then(function(response) { 
      return response || freshResource; 
     }); 
    }).catch(function (e) { 
     return freshResource; 
    }); 
    event.respondWith(cachedResource); 
}); 

Вся проблема возникла в том случае, когда элемент не присутствует в кэше и cache.match возвращается ошибка. Все, что мне нужно было сделать выборку фактического ответа сети в этом случае (Примечание return response || freshResource)

Этот ответ был Aha! момент для меня (хотя реализация отличается): Use ServiceWorker cache only when offline

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

  • Нет связанных вопросов^_^