HTTPQUERY
Русский

Content-Encoding

Применение

Заголовок Content-Encoding перечисляет кодирования, применённые к данным представления, в том порядке, в котором они были применены. Клиент проходит цепочку кодирований в обратном направлении, чтобы восстановить исходное содержимое. Самый распространённый сценарий — сжатие: оно уменьшает объём передаваемых данных ценой процессорного времени как на сервере, так и на клиенте.

Запросный заголовок Accept-Encoding сообщает, какие кодирования поддерживает клиент. Сервер выбирает кодирование из этого списка и указывает свой выбор в заголовке ответа Content-Encoding. Если приемлемого кодирования нет, сервер отправляет ответ без сжатия.

Когда присутствует Content-Encoding, заголовки метаданных вроде Content-Length относятся к закодированной форме, а не к исходному ресурсу. Предварительно сжатые медиаформаты, такие как JPEG, PNG и ZIP, уже содержат внутреннее сжатие и почти ничего не выигрывают от дополнительного прохода кодирования. Применение к ним кодирования содержимого расходует процессорное время, а иногда и увеличивает объём передачи.

Заголовок Content-Encoding описывает кодирование представления — сквозное (end-to-end) свойство ресурса. Этим он отличается от Transfer-Encoding, который является попрыжковым (hop-by-hop) свойством: оно применяется и снимается на каждом сетевом посреднике.

Примечание

gzip остаётся самым широко развёрнутым кодированием. Brotli обеспечивает наилучшую степень сжатия для статического текстового содержимого. Zstandard даёт баланс между быстрым сжатием и высокой степенью сжатия при широкой поддержке браузерами.

Примечание

Исходный медиатип ресурса описывается заголовком Content-Type. Content-Encoding отражает состояние сжатия текущего представления, а не формат лежащего в его основе содержимого.

gzip

Алгоритм кодирования Лемпеля — Зива (LZ77) с 32-битной CRC. Появившийся в 1996 году gzip по-прежнему остаётся самым широко поддерживаемым кодированием в вебе. Серверы также распознают псевдоним x-gzip.

compress

Алгоритм Лемпеля — Зива — Велча (LZW), изначально из программы compress в UNIX. Патентные претензии привели к упадку алгоритма, и ни один современный браузер не поддерживает compress.

deflate

Структура zlib, оборачивающая алгоритм deflate. Поддерживается всеми браузерами, но в значительной мере вытеснена gzip и более новыми алгоритмами.

br

Алгоритм Brotli. Brotli достигает более высокой степени сжатия, чем gzip, особенно на текстовом веб-содержимом, за счёт встроенного статического словаря распространённых веб-терминов. Brotli требует HTTPS. Поддерживается всеми основными браузерами.

zstd

Алгоритм Zstandard. Zstandard сжимает со скоростью, сопоставимой с gzip, достигая при этом степени сжатия, близкой к Brotli. Алгоритм поддерживает настраиваемые уровни сжатия от 1 (самый быстрый) до 22 (наибольшая степень сжатия), позволяя серверам обменивать процессорное время на меньший размер полезной нагрузки. Скорость распаковки остаётся неизменно высокой независимо от использованного уровня сжатия.

Zstandard также поддерживает сжатие на основе словаря: предварительно разделяемый словарь, обученный на репрезентативном содержимом, дополнительно уменьшает размер полезной нагрузки. Заголовок Use-As-Dictionary и механизм Compression Dictionary Transport построены именно на этой возможности.

Поддерживается браузерами на основе Chromium, Firefox и свежими версиями Safari.

dcb

Brotli со сжатием по словарю. Определён как часть спецификации Compression Dictionary Transport. Клиент и сервер согласуют общий словарь через заголовки Use-As-Dictionary и Available-Dictionary. Сервер сжимает ответ алгоритмом Brotli с использованием общего словаря и указывает кодирование как dcb.

dcz

Zstandard со сжатием по словарю. Использует тот же механизм передачи словаря, что и dcb, но с алгоритмом Zstandard вместо Brotli. Сервер сжимает с согласованным словарём и указывает кодирование как dcz.

Пример

Ответ, сжатый с помощью gzip. Это самое распространённое кодирование в вебе, поддерживаемое всеми браузерами.

Content-Encoding: gzip

Ответ, сжатый с помощью Brotli. Для ресурсов HTML, CSS и JavaScript Brotli обычно даёт меньшую полезную нагрузку, чем gzip.

Content-Encoding: br

Ответ, сжатый с помощью Zstandard. Серверы, выбирающие Zstandard, получают быстрое сжатие со степенью, сопоставимой с Brotli.

Content-Encoding: zstd

Несколько кодирований, применённых последовательно. Ресурс был сначала закодирован с помощью deflate, затем с помощью gzip. Клиент декодирует в обратном порядке: сначала gzip, затем deflate.

Content-Encoding: deflate, gzip

Ответ, использующий Zstandard со сжатием по словарю. Клиент ранее получил словарь через заголовок Use-As-Dictionary и объявил этот словарь в запросном заголовке Available-Dictionary. Сервер сжал ответ относительно общего словаря.

Content-Encoding: dcz

Диагностика

Сбои, связанные со сжатием, проявляются как ошибки декодирования в браузере, повреждённые загрузки или ответы, приходящие без сжатия.

Двойное сжатие приводит к повреждённым ответам. Обратный прокси или CDN повторно сжимает уже сжатый ответ от источника, порождая некорректную полезную нагрузку, которую клиент не может декодировать. Проверьте заголовок Content-Encoding на наличие составных значений вроде gzip, gzip. В nginx отключите сжатие на прокси, если источник уже сжимает:

proxy_set_header Accept-Encoding "";

В Cloudflare отключите «Brotli» в настройках Speed, если источник отдаёт предварительно сжатые ответы.

Браузер показывает ERR_CONTENT_DECODING_FAILED. Эта ошибка возникает, когда заголовок Content-Encoding объявляет кодирование, не соответствующее фактическому содержимому тела. Частые причины: источник отправляет несжатое тело с Content-Encoding: gzip, либо промежуточное ПО снимает кодирование, но оставляет заголовок на месте. Выполните curl -v -H “Accept-Encoding: gzip” https://example.re и проверьте, соответствует ли необработанное тело объявленному кодированию. Для проверки пропустите вывод через gunzip: curl -s —compressed https://example.re | head.

Несовпадение Content-Length после сжатия. Значение Content-Length должно отражать размер сжатого тела, а не исходного. Несовпадение приводит к тому, что браузеры обрезают или отвергают ответ. При использовании nginx с gzip on nginx пересчитывает Content-Length автоматически. Проблему вызывает промежуточное ПО, которое устанавливает Content-Length до выполнения сжатия. Перенесите присвоение Content-Length на момент после сжатия либо уберите этот заголовок и позвольте серверу использовать порционную передачу Transfer-Encoding.

Сжатие не применяется, несмотря на конфигурацию сервера. Перед сжатием сервер проверяет запросный заголовок Accept-Encoding. Отсутствующий или пустой Accept-Encoding означает отсутствие сжатия. Некоторые прокси удаляют Accept-Encoding из пересылаемых запросов. В nginx убедитесь, что установлено gzip on и что MIME-типы совпадают:

gzip on;
gzip_types text/plain application/json
           text/css application/javascript;

В Apache включите mod_deflate и убедитесь, что фильтр применяется:

AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/json

Раздача предварительно сжатых файлов для лучшей производительности. Сжатие при каждом запросе расходует процессорное время. Вместо этого раздавайте статические файлы, предварительно сжатые на диске. В nginx включите gzip_static on, чтобы отдавать файлы .gz рядом с оригиналами. В Apache включите MultiViews или используйте mod_rewrite для сопоставления запросов с вариантами .gz или .br. Следите за тем, чтобы предварительно сжатые файлы оставались синхронизированными с оригиналами при развёртываниях.