Могут ли рабочие службы реагировать на синхронные запросы XHR?

Я хотел бы использовать Service Workers для улучшения существующего веб-сайта. В частности, я хотел бы добавить лучшую поддержку в автономном режиме, если работники службы будут отвечать на запросы с использованием ресурсов-заполнителей, когда фактические ресурсы недоступны. Этот подход работал, но я столкнулся с препятствием. На сайте есть несколько мест, где синхронные запросы XHR используются для загрузки определенных ресурсов, и мой работник службы не получает события для них в Chrome. (Пожалуйста, не предлагайте исключать синхронные запросы XHR. Это желательно, но выходит за рамки.)

Должен ли работник службы обслуживания отвечать на синхронные запросы XHR? Я мог представить, что это сложно реализовать, и понял бы, если бы это не поддерживалось. Должен существовать "правильный" ответ между Спецификацией сервисных работников W3C (Рабочий проект) и Спецификацией выборки WHATWG (Уровень жизни), но я еще не закончил их расшифровку. Я был бы признателен за объяснение того, как спецификации описывают, следует ли это поддерживать или нет, и/или за любые ссылки на обсуждения по определению или реализации этого поведения.

Ответы

Ответ 1

Теоретически

Да, работники службы должны иметь возможность отвечать на синхронные запросы XHR. Это явно не указано в спецификациях, но нет исключения, которое могло бы привести к тому, что синхронные запросы XHR будут обрабатываться по-разному, а в комплекте тестов веб-платформы W3C (WPT) есть тестовый пример для проверки его поддержки: wpt/service-workers/service-worker/fetch-request-xhr-sync.https.html.

На практике

По состоянию на январь 2019 года сервисные работники могут отвечать на синхронные запросы XHR в Firefox и Edge, но не в Chrome или Safari. Chrome планирует добавить поддержку в ближайшее время, но мы не знаем, будет ли когда-либо Safari.

Актуальная матрица поддержки браузеров доступна на WPT.fyi. Вы можете запустить тестовый пример WPT в своем собственном браузере по адресу https://w3c-test.org/service-workers/service-worker/fetch-request-xhr-sync.https.html.

Ответ 3

Вы можете создать синхронный эффект, объединив асинхронные вызовы. Он создает отложенные обратные вызовы, в то время как promises сделает код более легким для чтения, но второй вызов Ajax не будет сделан до тех пор, пока не вернется 1-й. Обратите внимание, что для обоих вызовов 3-й параметр имеет значение 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 можно скопировать так же легко (но вертикально укладывать, вместо правого отступа), чтобы создать синхронный эффект.