HTTP POST с использованием XHR с кодированием фрагментированной передачи

У меня есть REST API, который принимает аудиофайл через HTTP-сообщение. В API есть поддержка Transfer-Encoding: заголовок запроса, разделенный на фрагменты, чтобы файл можно было загружать по частям, поскольку он создается с помощью устройства записи, работающего на клиенте. Таким образом, сервер может начать обработку файла по мере его поступления для повышения производительности. Например:

HTTP 1.1 POST .../v1/процессАудио

Передача-кодирование: по частям

[Чанк 1 256 байт] (сервер начинает обработку по прибытии)

[Чанк 2 256 байт]

[Чанк 3 256 байт]

...

Аудиофайлы обычно короткие и имеют размер от 10 до 100 КБ. У меня есть работающий код C# и Java, поэтому я знаю, что API работает. Однако я не могу заставить запись и загрузку работать в браузере с помощью javascript.

Вот мой тестовый код, который выполняет POST для локального хоста с Transfer-Encoding:

<html>
<script type="text/javascript">
  function streamUpload() {
    var blob = new Blob(['GmnQPBU+nyRGER4JPAW4DjDQC19D']);
    var xhr = new XMLHttpRequest();
    // Add any event handlers here...
    xhr.open('POST', '/', true);
    xhr.setRequestHeader("Transfer-Encoding", "chunked");
    xhr.send(blob);
  }
</script>

<body>
  <div id='demo'>Test Chunked Upload using XHR</div>
  <button onclick="streamUpload()">Start Upload</button>
</body>

</html>

Проблема в том, что я получаю следующую ошибку в Chrome

Отказался устанавливать небезопасный заголовок "Transfer-Encoding"

streamUpload @ uploadTest.html:14 onclick @ uploadTest.html:24

После просмотра документации XHR я все еще запутался, потому что в ней не говорится о небезопасных заголовках запросов. Мне интересно, возможно ли, что XHR не разрешает или не реализует Transfer-Encoding: chunked для HTTP POST?

Я рассмотрел обходные пути с использованием нескольких запросов XHR.send() и WebSockets, но оба они нежелательны, поскольку потребуют значительных изменений в серверных API, которые уже существуют, просты, стабильны и работают. Единственная проблема заключается в том, что мы не можем выполнить POST из браузера с псевдопотоковой передачей через Transfer-Encoding: chunked заголовок запроса.

Любые мысли или советы будут очень полезны.


person Mike Kennewick    schedule 22.07.2015    source источник
comment
Вам не разрешено устанавливать этот заголовок. Он контролируется пользовательским агентом. Проверьте спецификацию w3 здесь: w3.org/TR/XMLHttpRequest/# the-setrequestheader-method, особенно там, где он говорит: Вышеупомянутые заголовки контролируются пользовательским агентом, чтобы позволить ему управлять этими аспектами транспорта.   -  person Michael B.    schedule 22.07.2015


Ответы (1)


Как упоминалось в комментарии, вам не разрешено устанавливать этот заголовок, поскольку он контролируется пользовательским агентом.

Полный набор заголовков см. в 4.6.2 Метод setRequestHeader() из W3C XMLHttpRequest Level 1 и обратите внимание, что Transfer-Encoding — это один из заголовков, которые контролируются пользовательским агентом, что позволяет ему управлять этими аспектами транспорта.

  • Принять кодировку
  • Принять кодировку
  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Связь
  • Длина содержимого
  • Куки
  • Cookie2
  • Дата
  • ДНТ
  • Ожидать
  • Хозяин
  • Keep-Alive
  • Источник
  • Реферер
  • TE
  • Трейлер
  • Передача-кодирование
  • Обновление
  • Пользовательский агент
  • С помощью

Аналогичный список есть в стандарте жизни WhatWG Fetch API. https://fetch.spec.whatwg.org/#terminology-headers

person Kevin Hakanson    schedule 03.11.2015