получить поток ответа - PullRequest
       18

получить поток ответа

0 голосов
/ 03 июня 2018

В сервисном работнике я хочу вставить HTML в тело ответа HTTP:

При возврате кэшированного ответа HTML, я хочу аннотировать элемент <html> (например, превратить <html lang="en"> в * 1005).*) во время потоковой передачи исходного ответа до и после.

Я пытался реализовать это на основе потоков Джейка Арчибальда, порождающих , но не смог заставить что-либо работать.В приведенном ниже примере я хотел бы представить injectHTML, чтобы вернуть оболочку, которая преобразует часть исходного потока - но я понятия не имею, как туда добраться.Любые предложения будут оценены.

addEventListener("fetch", async event => {
    let request = event.request;
    if(request.method !== "GET" ||
            !request.headers.get("Accept").includes("text/html")) {
        return;
    }

    let response = await fetch(request);
    let stream = injectHTML(response.body);
    response = new Response(stream);
    event.respondWith(response);
});

1 Ответ

0 голосов
/ 05 июня 2018

Джейк streams объяснитель и содержащиеся в нем примеры - отличная отправная точка.

Наиболее актуальный пример - тот, который ... заменяет «облако» на «приклад» .

Код работника службы вместе с несколькими предостережениями можно найти на GitHub .

Для полноты, вот соответствующий код работника службы, который обрабатывает замену, но я бы рекомендовал проверить полный исходный код в контексте.

function replaceResponse(response, bufferSize, match, replacer) {
  const reader = response.body.getReader();
  const encoder = new TextEncoder();
  const decoder = new TextDecoder();
  let bufferStr = '';

  const stream = new ReadableStream({
    pull: controller => {
      return reader.read().then(result => {
        if (result.done) {
          controller.enqueue(encoder.encode(bufferStr));
          controller.close();
          return;
        }

        const bytes = result.value;
        bufferStr += decoder.decode(bytes, {stream: true});

        // this is the end of the final replacement in the FINAL string
        let lastReplaceEnds = 0;
        let replacedLengthDiff = 0;
        bufferStr = bufferStr.replace(match, (...args) => {
          const matched = args[0];
          // offset is the offset in the original string, hence replacedLengthDiff
          const offset = args[args.length - 2];
          const replacement = replacer(...args);

          replacedLengthDiff += replacement.length - matched.length;
          lastReplaceEnds = offset + matched.length + replacedLengthDiff;
          return replacement;
        });

        const newBufferStart = Math.max(bufferStr.length - bufferSize, lastReplaceEnds);
        controller.enqueue(encoder.encode(bufferStr.slice(0, newBufferStart)));
        bufferStr = bufferStr.slice(newBufferStart);
      });
    },
    cancel: () => {
      reader.cancel();
    }
  });

  return new Response(stream, {
    headers: response.headers
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...