Content-Encoding
Utilisation
L’en-tête Content-Encoding énumère les encodages appliqués aux données de représentation, dans l’ordre où ils ont été appliqués. Le client parcourt la chaîne d’encodage en sens inverse pour reconstituer le contenu d’origine. La compression en est le cas d’usage le plus courant : elle réduit la taille du transfert au prix de temps CPU, côté serveur comme côté client.
L’en-tête de requête Accept-Encoding annonce les encodages pris en charge par le client. Le serveur sélectionne un encodage dans la liste et indique son choix dans l’en-tête de réponse Content-Encoding. Lorsqu’aucun encodage acceptable n’existe, le serveur envoie la réponse non compressée.
Lorsque Content-Encoding est présent, les en-têtes de métadonnées comme Content-Length se rapportent à la forme encodée, et non à la ressource d’origine. Les formats média déjà compressés comme JPEG, PNG et ZIP contiennent une compression interne et ne gagnent que peu de chose à une passe d’encodage supplémentaire. Appliquer un encodage de contenu à ces formats gaspille du CPU et augmente parfois la taille du transfert.
L’en-tête Content-Encoding décrit l’encodage de la représentation, qui est une propriété de bout en bout de la ressource. Cela diffère de Transfer-Encoding, qui est une propriété saut par saut, appliquée et retirée à chaque intermédiaire réseau.
Remarque
gzip reste l’encodage le plus largement déployé. Brotli offre les meilleurs taux de compression pour les contenus textuels statiques. Zstandard offre un équilibre entre compression rapide et taux élevés, avec une large prise en charge par les navigateurs.
Remarque
Le type de média d’origine de la ressource est décrit par l’en-tête Content-Type. Content-Encoding reflète l’état de compression de la représentation courante, et non le format du contenu sous-jacent.
gzip
L’algorithme de codage Lempel-Ziv (LZ77) assorti d’un CRC 32 bits. Introduit en 1996, gzip demeure l’encodage le plus largement pris en charge sur le Web. Les serveurs reconnaissent également x-gzip comme alias.
compress
L’algorithme Lempel-Ziv-Welch (LZW), issu à l’origine du programme UNIX compress. Des questions de brevets ont entraîné le déclin de l’algorithme et aucun navigateur moderne ne prend en charge compress.
deflate
La structure zlib enveloppant l’algorithme deflate. Pris en charge par tous les navigateurs, mais largement supplanté par gzip et par des algorithmes plus récents.
br
L’algorithme Brotli. Brotli atteint des taux de compression supérieurs à ceux de gzip, en particulier sur les contenus web textuels, grâce à un dictionnaire statique intégré de termes courants du Web. Brotli exige HTTPS. Pris en charge par tous les principaux navigateurs.
zstd
L’algorithme Zstandard. Zstandard compresse à des vitesses comparables à gzip tout en atteignant des taux de compression plus proches de Brotli. L’algorithme accepte des niveaux de compression configurables de 1 (le plus rapide) à 22 (taux le plus élevé), ce qui permet aux serveurs d’échanger du temps CPU contre des charges utiles plus légères. La vitesse de décompression reste constamment rapide, quel que soit le niveau de compression utilisé.
Zstandard prend aussi en charge la compression par dictionnaire, où un dictionnaire pré-partagé entraîné sur des contenus représentatifs réduit encore la taille des charges utiles. L’en-tête Use-As-Dictionary et le mécanisme Compression Dictionary Transport s’appuient sur cette capacité.
Pris en charge par les navigateurs basés sur Chromium, Firefox et les versions récentes de Safari.
dcb
Brotli compressé par dictionnaire. Défini dans le cadre de la spécification Compression Dictionary Transport. Le client et le serveur négocient un dictionnaire partagé au moyen des en-têtes Use-As-Dictionary et Available-Dictionary. Le serveur compresse la réponse avec Brotli en utilisant le dictionnaire partagé et signale l’encodage comme dcb.
dcz
Zstandard compressé par dictionnaire. Utilise le même mécanisme de transport de dictionnaire que dcb, avec l’algorithme Zstandard à la place de Brotli. Le serveur compresse avec le dictionnaire négocié et signale l’encodage comme dcz.
Exemple
Une réponse compressée avec gzip. C’est l’encodage le plus courant sur le Web et il bénéficie d’une prise en charge universelle par les navigateurs.
Content-Encoding: gzip
Une réponse compressée avec Brotli. Brotli produit généralement des charges utiles plus petites que gzip pour les ressources HTML, CSS et JavaScript.
Content-Encoding: br
Une réponse compressée avec Zstandard. Les serveurs qui choisissent Zstandard profitent d’une compression rapide avec des taux comparables à Brotli.
Content-Encoding: zstd
Plusieurs encodages appliqués successivement. La ressource a d’abord été encodée avec deflate, puis avec gzip. Le client décode dans l’ordre inverse : gzip d’abord, puis deflate.
Content-Encoding: deflate, gzip
Une réponse utilisant Zstandard compressé par dictionnaire. Le client a précédemment reçu un dictionnaire via l’en-tête Use-As-Dictionary et l’a annoncé dans l’en-tête de requête Available-Dictionary. Le serveur a compressé la réponse en s’appuyant sur le dictionnaire partagé.
Content-Encoding: dcz
Dépannage
Les défaillances liées à la compression se manifestent par des erreurs de décodage dans le navigateur, des téléchargements corrompus ou des réponses arrivant non compressées.
La double compression produit des réponses corrompues. Un proxy inverse ou un CDN recompresse une réponse déjà compressée provenant de l’origine, produisant une charge utile invalide que le client ne peut pas décoder. Inspectez l’en-tête Content-Encoding à la recherche de valeurs empilées comme gzip, gzip. Dans nginx, désactivez la compression du proxy lorsque l’origine compresse déjà :
proxy_set_header Accept-Encoding "";
Dans Cloudflare, désactivez « Brotli » dans les réglages Speed lorsque l’origine envoie des réponses pré-compressées.
Le navigateur affiche ERR_CONTENT_DECODING_FAILED. Cette erreur apparaît lorsque l’en-tête Content-Encoding déclare un encodage qui ne correspond pas au contenu réel du corps. Causes fréquentes : l’origine envoie un corps non compressé avec Content-Encoding: gzip, ou un intergiciel supprime l’encodage mais laisse l’en-tête en place. Exécutez curl -v -H “Accept-Encoding: gzip” https://example.re et vérifiez si le corps brut correspond à l’encodage déclaré. Passez le résultat dans gunzip pour contrôler : curl -s —compressed https://example.re | head.
Incohérence de Content-Length après compression. La valeur de Content-Length doit refléter la taille du corps compressé, et non la taille d’origine. Une incohérence amène les navigateurs à tronquer ou à rejeter la réponse. Avec nginx gzip on, nginx recalcule automatiquement Content-Length. Un intergiciel qui fixe Content-Length avant l’exécution de la compression provoque ce problème. Déplacez l’affectation de Content-Length après la compression, ou supprimez l’en-tête et laissez le serveur utiliser un Transfer-Encoding chunked.
Compression non appliquée malgré la configuration du serveur. Le serveur consulte l’en-tête de requête Accept-Encoding avant de compresser. Un Accept-Encoding absent ou vide signifie aucune compression. Certains proxys retirent Accept-Encoding des requêtes transmises. Dans nginx, vérifiez que gzip on est défini et que les types MIME correspondent :
gzip on;
gzip_types text/plain application/json
text/css application/javascript;
Dans Apache, activez mod_deflate et vérifiez que le filtre est bien appliqué :
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/json
Servir des fichiers pré-compressés pour de meilleures performances. Compresser à chaque requête gaspille du CPU. Servez plutôt les fichiers statiques pré-compressés depuis le disque. Dans nginx, activez gzip_static on pour servir les fichiers .gz aux côtés des originaux. Dans Apache, activez MultiViews ou utilisez mod_rewrite pour rediriger les requêtes vers les variantes .gz ou .br. Veillez à ce que les fichiers pré-compressés restent synchronisés avec les originaux lors des déploiements.