Service Worker 可以响应同步的 XHR 请求吗?

Can Service Workers respond to synchronous XHR requests?

我想使用 Service Worker 来增强现有网站。特别是,我想通过让 Service Workers 在实际资源不可用时使用占位符资源响应请求来添加更好的离线支持。这种方法一直有效,但我遇到了障碍。站点中有几个地方 同步 XHR 请求用于加载某些资源,而我的 Service Worker 在 Chrome 中没有收到它们的事件。 (请不要建议消除同步 XHR 请求。这是需要的,但超出范围。)

Service Worker 是否应该可以响应同步 XHR 请求?我可以想象这实现起来很复杂,如果不支持它我会理解。在W3C Service Workers Specification (Working Draft) and the WHATWG Fetch Specification (Living Standard)之间应该有一个"correct"答案,但我还没有完成对它们的解读。如果能解释规范如何描述是否应支持此行为,我将不胜感激,and/or 对有关指定或实施此行为的讨论的任何参考。

根据 XMLHttpRequest spec, the fetch procedure for both synchronous and asynchronous requests is the same so, in theory, it should be intercepted but Synchronous XHR has been deprecated 所以我不希望 Chrome 解决这个问题。

您可以通过将异步调用链接在一起来创建同步效果。它创建缩进回调——而 promises 会使代码更易于阅读——但第二次 Ajax 调用将在第一个调用返回之后才会进行。请注意,第三个参数在两次调用中都设置为 true。

// Synchronized Ajax calls using 2 nested Asynchronous calls

// Asynchronous request #1 using traditional API
const axhr = new XMLHttpRequest();
axhr.open('GET', '/__so-example__', true);
axhr.onload = event => {
  console.log("A-XHR: " + axhr.responseText);

  // Asynchronous request #2 using traditional API
  const sxhr = new XMLHttpRequest();
  sxhr.open('GET', '/__so-example__', true);
  sxhr.onload = event => {
    console.log("S-XHR: " + sxhr.responseText);
  }
  sxhr.send();
}
axhr.send();

这只是一个例子。我认为 promises 可以很容易地链接起来(但垂直堆叠,而不是右缩进)以创建同步效果。

理论上

是的,服务工作者应该能够响应同步 XHR 请求。这在规范中没有明确说明,但没有例外会导致同步 XHR 请求被区别对待,W3C Web 平台测试 (WPT) 套件有一个测试用例来验证它是否受支持:wpt/service-workers/service-worker/fetch-request-xhr-sync.https.html .

实践中

自 2019 年 1 月起,Service Worker 可以在 Firefox 和 Edge 中响应同步 XHR 请求,但不能在 Chrome 或 Safari 中响应。 Chrome 是 planning to add support soon,但我们不知道 Safari 是否会这样做。

最新的浏览器支持矩阵可用at WPT.fyi. You can run the WPT test case in your own browser at https://w3c-test.org/service-workers/service-worker/fetch-request-xhr-sync.https.html