如何检查请求的响应是否来自Service Worker?

6
在Google Chrome控制台中,在HTTP 请求的状态代码旁边,我们有(来自ServiceWorker)的信息。

请求能否以某种方式意识到响应来自ServiceWorker?也许可以通过比较来自响应头部日期来判断。
1个回答

10
按照设计,通过FetchEvent#respondWith()返回的响应应该与没有使用service worker参与的响应无法区分。无论我们讨论的响应是通过XMLHttpRequestwindow.fetch()还是设置某个元素的src=属性获得的。

如果你重视区分哪些响应是由service worker参与产生的,则我能想到最干净的方法是在传递给FetchEvent#respondWith()Response对象中显式添加HTTP头。然后你可以从受控页面检查该头。

然而,这取决于你的service worker如何获取其Response,这可能有点棘手/不可靠,除非你有一个强烈的用例。以下是一种(再次强调,不建议)方法:

event.respondWith(
  return fetch(event.request).then(function(response) {
    if (response.type === 'opaque') {
      return response;
    }

    var headersCopy = new Headers(response.headers);
    headersCopy.set('X-Service-Worker', 'true');

    return response.arrayBuffer().then(function(buffer) {
      return new Response(buffer, {
        status: response.status,
        statusText: response.statusText,
        headers: headersCopy
      });
    });
  })
)

如果你得到一个不透明的Response,除了直接返回给页面外,你不能做太多事情。否则,它将复制一堆东西到一个新的Response中,并设置一个名为X-Service-Worker的标头为true。(这是绕开无法直接修改fetch()返回的Responseheaders的方法。)

谢谢,Jeff。那个问题是你之前的回答(https://dev59.com/VIrda4cB1Zd3GeqPHxcg#29922616)的结果,你指出了“确保用户知道他们的HTTP POST正在排队”。怎样才能最好地让用户(应用程序)意识到这一点?我认为额外的标头会是一个不错的选择,因为ServiceWorkers是代理并处理整个获取/缓存/响应操作。因此,应用程序本身没有其他选项来意识到它处于离线状态。 - Karol Klepacki
2
我认为你应该从受控页面而不是服务工作者中重放请求,以便请求权限/通知用户。如果你将它们排队在IDB中,那么你可以通过受控页面轻松地加载它们。如果你使用Cache Storage API将它们排队,你可以在Chrome 43+中使用window.caches来加载它们。由于你的受控页面知道这是一个重放请求,所以你不需要服务工作者添加特殊的头文件或其他任何东西。 - Jeff Posnick
你不觉得这是反模式吗?在现代软件开发中,我们希望为特定的代码部分设置层,并将SW视为可编程网络代理,我们的应用程序只需关心发送请求,而SW应执行所有必要的操作使其正常工作。它有一些独特的手段来做到这一点,比如后台同步。我认为我们应该在Alex的GitHub上继续讨论这个问题。 - Karol Klepacki
2
仅使用SW参与在“后台”重放,对于像Analytics pings这样的事情有意义。但我们刚刚添加了离线My Schedule更改的重放到https://events.google.com/io2015/,我可以说从经验来看,我们别无选择,只能从受控页面启动它。仅受控页面可以访问新鲜的OAuth 2令牌。从受控页面启动回放也使通知用户何时完成更容易,而无需添加“hacky”标题。 - Jeff Posnick
非常有用的回答(像往常一样)@JeffPosnick。一个问题:当您创建新的“Response”时,您是否应该从“response”复制“status”和“statusText”属性?您是否也应该复制其他属性,例如“ok”,“type”和“url”?(即此处列出的属性:https://developer.mozilla.org/zh-CN/docs/Web/API/Response#Properties) - drmrbrewer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接