Javascript服务工作者:从缓存中获取资源,但也更新它

时间:2016-09-07 07:39:47

标签: javascript caching promise service-worker

我正在使用chrome上的服务工作者来缓存网络响应。当客户端请求资源时我打算做什么:

检查缓存 - 如果存在,则从缓存返回,但如果文件与缓存版本不同,还会向服务器发送请求并更新缓存。 如果缓存没有缓存,请向服务器发送请求,然后缓存响应。

这是我目前执行相同操作的代码:

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;
    }));
});

此代码无效,因为它会抛出错误:

  

url 的FetchEvent导致网络错误响应:一个不是响应的对象被传递给respondWith()。

有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:3)

好的,在人们指出建议(谢谢你)并找到解决方案之后,我摆弄了代码。

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