如何在event.respondWith()中回退到浏览器的默认提取处理?

时间:2018-04-27 12:09:25

标签: javascript service-worker fetch-api

在服务工作者中,我的提取处理程序如下所示:

self.addEventListener('fetch', function (event) {
  event.respondWith(
    caches.match(event.request).then(function (response) {
      return response || fetch(event.request); //<-- is this the browser's default fetch handling?
    })
  );
});

方法event.respondWith()强迫我自己处理所有请求,包括xhr请求,这不是我喜欢的待办事项。我只希望在可用的情况下返回缓存的资源,并让浏览器使用浏览器的默认提取处理来处理其余的资源。

fetch(event.request)我有两个问题:

  1. 只有在打开devtools时,才会在获取地址栏https://test.de/x/#/page中显示的初始URL时生成error。它在初始安装和每次重新加载时都会发生:

      

    未捕获(承诺)TypeError:无法在'ServiceWorkerGlobalScope'上执行'fetch':'only-if-cached'只能使用'same-origin'模式设置`

    我不明白为什么因为我没有设置任何东西

  2. 它似乎违反了HTTP协议,因为它试图请求一个带有锚点的URL:

      

    控制台:{“lineNumber”:0,“message”:“FetchEvent for   \“https://test.de/x/#/page \”导致网络错误   回复:承诺被拒绝。“,”message_level“:2,”sourceIdentifier“:1,”sourceURL“:”“}``

  3. fetch()与浏览器的默认提取处理有何不同,这些差异是造成这些错误的原因吗?

    其他信息和代码:

    我的应用程序还利用好的旧appCache与服务工作者并行(为了向后兼容)。我不确定appcache是​​否会干扰初始页面加载时的服务工作者安装。其余代码非常简单:

    我在https://test.de/x/#/page的index.html使用appcache和base-href:

    <html manifest="appcache" lang="de">
    <head>
       <base href="/x/"/>
    </head>
    ...
    

    正文脚本中的服务工作者注册

    window.addEventListener('load', {
      navigator.serviceWorker.register('/x/sw.js')
    });
    

    安装并激活活动

    let MY_CACHE_ID = 'myCache_v1';
    let urlsToCache = ['js/main.js'];
    self.addEventListener('install', function (event) {
      event.waitUntil(
        caches.open(MY_CACHE_ID)
          .then(function (cache) {        
            return cache.addAll(
              urlsToCache.map(url => new Request(url, 
              {credentials:'include'}))
            )
          })
      );
    });
    
    self.addEventListener('activate', function (event) {
      //delete old caches
      let cacheWhitelist = [MY_CACHE_ID];
      event.waitUntil(
        caches.keys().then(function (cacheNames) {
          return Promise.all(
            cacheNames.map(function (cacheName) {
              if (cacheWhitelist.indexOf(cacheName) === -1) {
                return caches.delete(cacheName);
              }
            })
          );
        })
      );
    });
    

1 个答案:

答案 0 :(得分:3)

fetch(event.request)应该非常接近默认值。 (你可以通过不调用respondWith()来获得实际的默认值。它应该不是可观察的,而是使用CSP和一些引用位。)

鉴于此,我不确定你是如何以1结束的。这应该是不可能的。遗憾的是,您没有提供足够的信息来调试正在发生的事情。

对于2,它将片段传递给服务工作者,但不会包含在最终的网络请求中。这与Fetch的定义方式相匹配,并以这种方式完成,以便为服务工作者提供一些可能有用的附加上下文。