Кодовая кодировка передачи - поведение браузера
Я пытаюсь отправить данные в режиме chunked. Все заголовки установлены правильно, и данные кодируются соответствующим образом. Браузеры распознают мой ответ как разделенный, принимают заголовки и начинают получать данные.
Я ожидал, что браузер обновит страницу на каждом полученном фрагменте, вместо этого он ждет, пока все куски не будут получены, а затем отобразит их все. Это ожидаемое поведение?
Я ожидал увидеть каждый кусок, показанный сразу после его получения. При использовании curl
каждый фрагмент отображается сразу после его получения. Почему такое же не происходит с GUI-браузерами? Используют ли они какую-то буферизацию/кеш?
Я устанавливаю заголовок Cache-Control
на no-cache
, поэтому не уверен, что он относится к кешу.
Ответы
Ответ 1
В браузерах afaik нужна некоторая полезная нагрузка для начала обработки кусков по мере их поступления.
Curl - это, конечно, исключение.
Попробуйте отправить около 1 Кбайт произвольных данных перед первым куском.
Если вы все делаете правильно, браузеры должны отображать куски по мере их получения.
Ответ 2
Исправьте свои заголовки.
1) Начиная с 2019 года, если вы используете Content-type: text/html
, в Chrome буферизация не происходит.
2) Если вы просто хотите транслировать текст, аналогично text/plain
, то использование Content-type: text/event-stream
также отключит буферизацию.
3) Если вы используете Content-type: text/plain
, то Chrome по-прежнему будет буферизовать 1 КиБ, если вы не укажете дополнительно X-Content-Type-Options: nosniff
.
В RFC 2045 указано, что если не указан Content-Type
, следует предположить Content-type: text/plain; charset=us-ascii
5.2. Content-Type Defaults
По умолчанию принимаются сообщения RFC 822 без заголовка MIME Content-Type. по этому протоколу, чтобы быть простым текстом в наборе символов US-ASCII, который может быть явно указан как:
Content-type: text/plain; charset=us-ascii
Это значение по умолчанию предполагается, если не указано поле заголовка Content-Type. Также рекомендуется принять это значение по умолчанию, когда синтаксически недопустимое поле заголовка Content-Type. В наличие поля заголовка MIME-версии и отсутствие каких-либо Поле заголовка Content-Type, принимающий пользовательский агент также может принять этот простой текст US-ASCII был намерением отправителя. Обычная US-ASCII текст все еще может быть принят в отсутствие MIME-версии или наличие синтаксически неверного поля заголовка Content-Type, но намерение отправителя могло быть иным.
Браузеры начнут буферизовать text/plain
на определенное количество, чтобы проверить, могут ли они определить, является ли отправленное содержимое действительно обычным текстом или каким-либо другим типом мультимедиа, например изображением, в случае, если Content-Type
был опущен, что тогда равнялось бы text/plain
тип контента. Это называется анализом MIME-типа.
Обнаружение MIME-типа определяется Mozilla как:
В отсутствие MIME-типа или в некоторых случаях, когда браузеры если они неверны, браузеры могут выполнять анализ MIME - угадав правильный тип MIME, посмотрев на байты ресурс.
Каждый браузер выполняет анализ MIME по-разному и по-разному обстоятельства. (Например, Safari будет смотреть на расширение файла в URL-адрес, если отправленный тип MIME не подходит.) Есть безопасность относится к тому, что некоторые типы MIME представляют исполняемый контент. Серверы могут предотвратить прослушивание MIME, отправив заголовок X-Content-Type-Options.
Согласно документации Mozilla:
HTTP-заголовок ответа X-Content-Type-Options
является маркером, используемым сервер, чтобы указать, что типы MIME, объявленные в Заголовки Content-Type
не должны быть изменены и должны соблюдаться. Этот позволяет отказаться от прослушивания MIME-типа, или, другими словами, это способ сказать, что веб-мастера знали, что они делают.
Поэтому добавление X-Content-Type-Options: nosniff
заставляет его работать.
Ответ 3
Браузер может обрабатывать и отображать данные в том виде, в каком они отправляются, или нет. Независимо от того, отображает ли браузер данные ответа, будет ли функция структуры данных и какой буферизацией она использует. например Прежде чем браузер сможет отобразить изображение, он должен иметь документ (или достаточно документа), таблицу стилей и т.д.
Chunking в основном полезен, когда длина ресурса неизвестна в момент генерации ответа ресурса ( "Content-Length" не может быть включен в заголовки ответов), и сервер не хочет закрывать соединение после передачи ресурса.