20

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

Service Worker 应该可以响应同步 XHR 请求吗?我可以想象这实现起来很复杂,如果不支持它会理解的。W3C Service Workers Specification (Working Draft)WHATWG Fetch Specification (Living Standard)之间应该存在一个“正确”的答案,但我还没有完成对它们的解读。我希望能解释一下规范如何描述是否应该支持这一点,和/或对有关指定或实现此行为的讨论的任何引用。

4

3 回答 3

6

根据XMLHttpRequest 规范同步和异步请求的获取过程相同的,所以理论上应该被拦截,但同步 XHR 已被弃用,所以我不希望 Chrome 修复这个问题。

于 2016-03-09T13:22:30.947 回答
6

理论上

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

在实践中

自 2019 年 1 月起,服务工作者可以在 Firefox 和 Edge 中响应同步 XHR 请求,但不能在 Chrome 或 Safari 中响应。Chrome计划很快添加支持,但我们不知道 Safari 是否会。

WPT.fyi提供了最新的浏览器支持矩阵。您可以在自己的浏览器中运行 WPT 测试用例,网址为https://w3c-test.org/service-workers/service-worker/fetch-request-xhr-sync.https.html

于 2019-01-23T02:39:57.323 回答
0

您可以通过将异步调用链接在一起来创建同步效果。它创建缩进的回调——而promise 会使代码更易于阅读——但是直到第一个Ajax 调用返回后才会进行第二个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();

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

于 2016-03-16T23:26:11.940 回答