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

Posted

技术标签:

【中文标题】Service Worker 可以响应同步的 XHR 请求吗?【英文标题】:Can Service Workers respond to synchronous XHR requests? 【发布时间】:2016-06-23 03:13:32 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

理论上

是的,Service Worker 应该能够响应同步 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。您可以在自己的浏览器中运行 WPT 测试用例https://w3c-test.org/service-workers/service-worker/fetch-request-xhr-sync.https.html。

【讨论】:

我认为“计划尽快添加支持”部分可以删除,因为已经两年了,而且从 cmets 来看,他们没有将这个设置作为优先事项。 重要提示: Service Worker 似乎能够响应从 Web Worker 发送的同步 XHR 请求 - 至少在我目前的实验中.我对此没有任何官方信息,所以我不知道它是否得到保证,但我已经测试了 Firefox、Chrome 和 Safari。从网络工作者发送请求是我的用例,这篇文章让我很担心,但是当我查看 WPT 测试用例时,我猜想它不起作用的原因可能是(希望如此)因为请求是从主服务器发送的线程。【参考方案2】:

您可以通过将异步调用链接在一起来创建同步效果。它创建缩进的回调——而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 可以很容易地链接起来(但垂直堆叠,而不是右缩进)以创建同步效果。

【讨论】:

这在 Chrome 中是不可能的。查看这些链接:***.com/questions/27693814/…developers.google.com/web/updates/2012/01/… 根据这篇 Chromium Bugs 列表帖子的评论 #23-27,同步 XHR 应该仍然适用于 Chrome:bugs.chromium.org/p/chromium/issues/detail?id=392311 我不知道为什么它不适用于上面的代码示例:“S -XHR:[未找到]”,但我试图帮助您解决这个问题。这些链接只是表明人们之前曾在 SO 上问过“Chrome 和其他浏览器会放弃对同步 XMLHttpRequest 的支持吗?” SO 上的答案建议“是”,但 Chrome 开发人员说“不”:***.com/questions/30876093/…【参考方案3】:

根据XMLHttpRequest spec,fetch procedure for both synchronous and asynchronous requests 是same,所以理论上应该被拦截,但Synchronous XHR has been deprecated 所以我不希望 Chrome 修复这个问题。

【讨论】:

以上是关于Service Worker 可以响应同步的 XHR 请求吗?的主要内容,如果未能解决你的问题,请参考以下文章

Service Worker 中的同步或顺序获取

Service Worker:如何处理 302 重定向响应

Service Worker基础知识整理

Service Worker 是不是会不断地从服务器请求、响应?

Service worker 简介

Service worker 简介