Content-Encoding
Uso
La cabecera Content-Encoding enumera las codificaciones aplicadas a los datos de la representación, en el orden en que se aplicaron. El cliente recorre la cadena de codificación en sentido inverso para reconstruir el contenido original. La compresión es el caso de uso más habitual: reduce el tamaño de la transferencia a costa de tiempo de CPU tanto en el servidor como en el cliente.
La cabecera de solicitud Accept-Encoding anuncia qué codificaciones admite el cliente. El servidor selecciona una codificación de la lista e indica su elección en la cabecera de respuesta Content-Encoding. Cuando no existe ninguna codificación aceptable, el servidor envía la respuesta sin comprimir.
Cuando Content-Encoding está presente, las cabeceras de metadatos como Content-Length se refieren a la forma codificada, no al recurso original. Los formatos multimedia precomprimidos como JPEG, PNG y ZIP ya incorporan compresión interna y apenas ganan nada con una pasada de codificación adicional. Aplicar una codificación de contenido a estos formatos desperdicia CPU y a veces aumenta el tamaño de la transferencia.
La cabecera Content-Encoding describe la codificación de la representación, que es una propiedad de extremo a extremo del recurso. Esto difiere de Transfer-Encoding, que es una propiedad salto a salto aplicada y retirada en cada intermediario de la red.
Nota
gzip sigue siendo la codificación con mayor despliegue. Brotli ofrece las mejores relaciones de compresión para contenido textual estático. Zstandard proporciona un equilibrio entre compresión rápida y buenas relaciones, con amplio soporte en los navegadores.
Nota
El tipo de medio original del recurso lo describe la cabecera Content-Type. Content-Encoding refleja el estado de compresión de la representación actual, no el formato del contenido subyacente.
gzip
El algoritmo de codificación Lempel-Ziv (LZ77) con un CRC de 32 bits. Introducido en 1996, gzip sigue siendo la codificación con mayor soporte en la web. Los servidores también reconocen x-gzip como alias.
compress
El algoritmo Lempel-Ziv-Welch (LZW), procedente originalmente del programa compress de UNIX. Los problemas de patentes provocaron el declive del algoritmo y ningún navegador moderno admite compress.
deflate
La estructura zlib que envuelve el algoritmo deflate. Admitido por todos los navegadores, pero en gran medida superado por gzip y por algoritmos más recientes.
br
El algoritmo Brotli. Brotli alcanza relaciones de compresión más altas que gzip, especialmente en contenido web basado en texto, gracias a un diccionario estático integrado de términos web habituales. Brotli requiere HTTPS. Lo admiten todos los navegadores principales.
zstd
El algoritmo Zstandard. Zstandard comprime a velocidades comparables a gzip y a la vez logra relaciones de compresión cercanas a las de Brotli. El algoritmo admite niveles de compresión configurables, de 1 (el más rápido) a 22 (la mayor relación), lo que permite a los servidores cambiar tiempo de CPU por cargas útiles más pequeñas. La velocidad de descompresión se mantiene siempre rápida, sea cual sea el nivel de compresión utilizado.
Zstandard también admite compresión basada en diccionario, donde un diccionario precompartido entrenado con contenido representativo reduce aún más el tamaño de las cargas útiles. La cabecera Use-As-Dictionary y el mecanismo Compression Dictionary Transport se apoyan en esta capacidad.
Lo admiten los navegadores basados en Chromium, Firefox y las versiones recientes de Safari.
dcb
Brotli comprimido con diccionario. Definido como parte de la especificación Compression Dictionary Transport. El cliente y el servidor negocian un diccionario compartido mediante las cabeceras Use-As-Dictionary y Available-Dictionary. El servidor comprime la respuesta con Brotli usando el diccionario compartido y señala la codificación como dcb.
dcz
Zstandard comprimido con diccionario. Utiliza el mismo mecanismo de transporte de diccionarios que dcb, pero con el algoritmo Zstandard en lugar de Brotli. El servidor comprime con el diccionario negociado y señala la codificación como dcz.
Ejemplo
Una respuesta comprimida con gzip. Es la codificación más común en la web y cuenta con soporte universal en los navegadores.
Content-Encoding: gzip
Una respuesta comprimida con Brotli. Brotli suele producir cargas útiles más pequeñas que gzip para recursos HTML, CSS y JavaScript.
Content-Encoding: br
Una respuesta comprimida con Zstandard. Los servidores que eligen Zstandard se benefician de una compresión rápida con relaciones comparables a las de Brotli.
Content-Encoding: zstd
Varias codificaciones aplicadas en secuencia. El recurso se codificó primero con deflate y después con gzip. El cliente decodifica en orden inverso: primero gzip, luego deflate.
Content-Encoding: deflate, gzip
Una respuesta que usa Zstandard comprimido con diccionario. El cliente había recibido previamente un diccionario mediante la cabecera Use-As-Dictionary y lo anunció en la cabecera de solicitud Available-Dictionary. El servidor comprimió la respuesta contra el diccionario compartido.
Content-Encoding: dcz
Diagnóstico
Los fallos relacionados con la compresión se manifiestan como errores de decodificación en el navegador, descargas corruptas o respuestas que llegan sin comprimir.
La doble compresión produce respuestas corruptas. Un proxy inverso o una CDN vuelve a comprimir una respuesta del origen que ya estaba comprimida, generando una carga útil inválida que el cliente no puede decodificar. Revise la cabecera Content-Encoding en busca de valores apilados como gzip, gzip. En nginx, desactive la compresión del proxy cuando el origen ya comprime:
proxy_set_header Accept-Encoding "";
En Cloudflare, desactive “Brotli” en los ajustes de Speed cuando el origen envía respuestas precomprimidas.
El navegador muestra ERR_CONTENT_DECODING_FAILED. Este error aparece cuando la cabecera Content-Encoding declara una codificación que no coincide con el contenido real del cuerpo. Causas habituales: el origen envía un cuerpo sin comprimir con Content-Encoding: gzip, o un middleware elimina la codificación pero deja la cabecera intacta. Ejecute curl -v -H “Accept-Encoding: gzip” https://example.re e inspeccione si el cuerpo en bruto coincide con la codificación declarada. Canalice la salida por gunzip para verificarlo: curl -s —compressed https://example.re | head.
Discrepancia de Content-Length tras la compresión. El valor de Content-Length debe reflejar el tamaño del cuerpo comprimido, no el tamaño original. Una discrepancia hace que los navegadores trunquen o rechacen la respuesta. Al usar nginx con gzip on, nginx recalcula Content-Length automáticamente. El middleware que establece Content-Length antes de que se ejecute la compresión provoca este problema. Traslade la asignación de Content-Length a después de la compresión, o elimine la cabecera y deje que el servidor use Transfer-Encoding por fragmentos.
No se aplica compresión a pesar de la configuración del servidor. El servidor comprueba la cabecera de solicitud Accept-Encoding antes de comprimir. Un Accept-Encoding ausente o vacío significa que no hay compresión. Algunos proxies eliminan Accept-Encoding de las solicitudes reenviadas. En nginx, verifique que gzip on esté configurado y que los tipos MIME coincidan:
gzip on;
gzip_types text/plain application/json
text/css application/javascript;
En Apache, habilite mod_deflate y verifique que el filtro se aplica:
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/json
Sirva archivos precomprimidos para obtener mejor rendimiento. Comprimir en cada solicitud desperdicia CPU. En su lugar, sirva los archivos estáticos precomprimidos desde disco. En nginx, habilite gzip_static on para servir archivos .gz junto a los originales. En Apache, habilite MultiViews o use mod_rewrite para asignar las solicitudes a las variantes .gz o .br. Asegúrese de que los archivos precomprimidos se mantengan sincronizados con los originales durante los despliegues.