ERR_FAILED,当服务人员加载新页面时,为什么?

时间:2018-08-19 15:39:33

标签: javascript caching service-worker

我已经在教程的帮助下写了一个服务工作者:

var CACHE = 'cache-and-update';

self.addEventListener('install', function (evt) {
    console.log('The service worker is being installed.');

    evt.waitUntil(precache());
});

self.addEventListener('fetch', function (evt) {

    evt.respondWith(fromCache(evt.request));

    evt.waitUntil(update(evt.request));
});

function precache() {
    return caches.open(CACHE).then(function (cache) {
        return cache.addAll([
            // Nothing.
        ]);
    });
}

function fromCache(request) {
    return caches.open(CACHE).then(function (cache) {
        return cache.match(request).then(function (matching) {
            return matching || Promise.reject('no-match');
        });
    });
}

function update(request) {
    return caches.open(CACHE).then(function (cache) {
        return fetch(request).then(function (response) {
            return cache.put(request, response);
        });
    });
}

始终总是先从缓存中提供服务,然后获取所有文件,并在页面重新加载时进行更新。

在我的服务器上的每个HTML文件中,服务工作者都是这样注册的:

<script>
    navigator.serviceWorker.register('https://www.example.com/sw.js', {
        scope: '../'
    });
</script>

现在的问题是,当我转到尚未缓存的页面时,它首先向我显示默认的Chrome ERR_FAILED错误(以及“不匹配”的承诺被拒绝)。

然后,无论如何,sw都会获取它,同时向客户端显示错误页面,并在重新加载后再次起作用(因为它是从缓存中提供的)。

为什么会发生这种情况?当没有可用的缓存版本时,如何使服务工作者从服务器加载页面?

1 个答案:

答案 0 :(得分:1)

您在这里错误地获取了监听器, 如果您在缓存中找不到文件,则拒绝诺言,您应该先获取文件然后缓存它,而不是返回Promise.reject('no-match'),并且在这种情况下不需要evt.waitUntil

这是服务中的工作人员的完整摘要。如果请求与缓存中的任何内容都不匹配,我们将从网络中获取该请求,将其发送到页面,然后同时将其添加到缓存中。

let cacheName = 'cache-v1';

self.addEventListener('install', (e) => {

  let cache = caches.open(cacheName).then((c) => {
    c.addAll([
      // nothing
    ]);
  });

  e.waitUntil(cache);
});

self.addEventListener('fetch', function (event) {

  event.respondWith(

    caches.open(cacheName).then(function (cache) {
      return cache.match(event.request).then(function (response) {
        return response || fetch(event.request).then(function (response) {
          cache.put(event.request, response.clone());
          return response;
        });
      });
    })

  );

});