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

标签 javascript service-worker fetch-api

在服务 worker 中,我的获取处理程序如下所示:

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 打开时,它才会生成 error同时获取地址栏中可见的初始 URL https://test.de/x/#/page。它发生在初始安装和每次重新加载时:

    Uncaught (in promise) TypeError: Failed to execute 'fetch' on 'ServiceWorkerGlobalScope': 'only-if-cached' can be set only with 'same-origin' mode`

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

  2. 它似乎违反了 HTTP 协议(protocol),因为它尝试请求内部带有 anchor 的 URL:

    Console: {"lineNumber":0, "message":"The FetchEvent for \"https://test.de/x/#/page\" resulted in a network error response: the promise was rejected.", "message_level":2, "sourceIdentifier":1, "sourceURL":""}`

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

其他信息和代码:

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

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

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

主体脚本中的 Service Worker 注册

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

最佳答案

fetch(event.request) 应该非常接近默认值。 (您可以通过根本不调用 respondWith() 来获得实际的默认值。它大多数情况下应该是不可观察的,但与 CSP 和一些引用位有关。)

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

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

关于javascript - 如何在 event.respondWith() 中回退到浏览器的默认获取处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50062084/

相关文章:

javascript - API Fetch 仅更新一项数据

javascript - 获得 promise 值(value)

JavaScript:在 Android 上阻止文本输入时的退格键

javascript - 新记录出现在表格底部?

javascript - ui-grid表格PDF导出

service-worker - 是否可以在 PWA 未打开时使用 Service Worker 跟踪地理位置

javascript - jQuery/JS - IE 错误 - 对象不支持属性或方法 'hasClass'

Javascript - 在 Android 设备上单击服务工作人员通知后打开浏览器选项卡

javascript - 向请求添加新 header ,同时保留正文

javascript - 获取 API - 定位 Iframe