Используйте ReadableStream с Response для возврата HTML из события выборки Service Worker - PullRequest
2 голосов
/ 18 июня 2020

Я пытаюсь вернуть поток для ответа HTML в сервис-воркере, но браузер, похоже, не может его проанализировать (я использую chrome для этого теста).

Итак, это работает (в событии fetch):

event.respondWith(new Response("<h1>Yellow!</h1>", { headers: { "Content-Type": "text/html" }}))

Но когда я использую ReadableStream, он больше не отображается в браузере:

const stream = new ReadableStream({
    start(controller) {
        controller.enqueue("<h1>Yellow!</h1>")
        controller.close()
    }
})
event.respondWith(new Response(stream, { headers: { "Content-Type": "text/html" }}))

Похоже, браузер не понимает, что я отправляю ему поток. Но я не знаю, какие заголовки мне нужно использовать, чтобы все вышеперечисленное работало.

Ресурсы, которые я использовал:

https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#Examples

https://philipwalton.com/articles/smaller-html-payloads-with-service-workers/

ОБНОВЛЕНИЕ

Мой вопрос похож на этот, но для асинхронного случая.

1 Ответ

2 голосов
/ 18 июня 2020

По какой-то причине это не работает, если вы не блокируете поток с помощью ReadableStream.getReader

Также, когда вы передаете ReadableStream в Response ctor , метод Response.text не обрабатывает поток и вместо этого возвращает toString() объекта.

const createStream = () => new ReadableStream({
  start(controller) {
    controller.enqueue("<h1 style=\"background: yellow;\">Yellow!</h1>")
    controller.close()
  }
})

const firstStream = createStream().getReader();
const secondStream = createStream().getReader();

new Response(firstStream, {
      headers: {
        "Content-Type": "text/html"
      }
    })
  .text()
  .then(text => {
    console.log(text);
  });
    

secondStream.read()
  .then(({
    value
  }) => {

    return new Response(value, {
      headers: {
        "Content-Type": "text/html"
      }
    });

  })
  .then(response => response.text())
  .then(text => {
    console.log(text);
  });
...