Vary
Utilisation
Une même URL produit souvent des réponses différentes selon ce que le client envoie. Un serveur qui compresse en gzip pour un client et en Brotli pour un autre sert deux représentations distinctes de la même ressource. L’en-tête Vary consigne quels en-têtes de requête ont conduit le serveur à choisir une représentation particulière, ce qui donne aux caches l’information nécessaire pour stocker et faire correspondre la bonne copie.
Lorsqu’un cache reçoit une requête pour une URL dont il détient une réponse stockée, il compare les en-têtes listés dans Vary entre la nouvelle requête et celle qui a été stockée. Si les valeurs correspondent, la réponse mise en cache est valide. Si elles diffèrent, le cache récupère une nouvelle réponse auprès du serveur d’origine.
Les valeurs les plus courantes sont Accept-Encoding (pour la négociation de compression) et Accept (pour la négociation de contenu). Les configurations de diffusion dynamique qui servent un HTML différent aux clients mobiles et aux clients de bureau en fonction de la chaîne User-Agent ajoutent Vary: User-Agent pour signaler cette variation.
La valeur générique * signifie que chaque requête est considérée comme unique et désactive de fait la mise en cache de la ressource. C’est rarement approprié et la plupart des caches traitent une réponse Vary: * comme non cacheable.
Remarque
Google n’utilise pas l’en-tête Vary pour comprendre les relations entre versions mobile et bureau lors de l’indexation. Cet en-tête est un mécanisme de mise en cache, pas un signal de recherche. Les sites recourant à la diffusion dynamique avec Vary: User-Agent bénéficient toujours d’un comportement de cache correct, mais l’en-tête lui-même n’a aucun effet sur la façon dont Google découvre ou indexe le contenu mobile. Google déconseille également de faire des URL m-dot la version canonique malgré l’indexation mobile-first, et recommande le responsive design comme configuration à privilégier.
Accept-Encoding
Indique que la réponse varie selon l’en-tête de requête Accept-Encoding. Différents algorithmes de compression (gzip, br, zstd) produisent des corps de réponse différents pour la même ressource. C’est la valeur de Vary la plus largement utilisée.
Accept
Indique que la réponse varie selon l’en-tête de requête Accept. La négociation de contenu délivre différents types de média (HTML, JSON, XML) depuis la même URL selon la préférence du client.
Accept-Language
Indique que la réponse varie selon l’en-tête de requête Accept-Language. Les sites multilingues qui servent du contenu localisé depuis la même URL incluent cette valeur.
User-Agent
Indique que la réponse varie selon l’en-tête de requête User-Agent. Les configurations de diffusion dynamique délivrent un HTML différent aux clients mobiles et de bureau depuis la même URL.
Cookie
Vary: Cookie signifie que la réponse diffère selon la valeur de l’en-tête Cookie. Les caches stockent une variante distincte pour chaque chaîne Cookie unique, ce qui provoque une forte fragmentation du cache puisque chaque utilisateur authentifié possède un cookie de session différent. Limitez Vary: Cookie aux réponses qui dépendent réellement des valeurs de cookie (pages personnalisées, tableaux de bord) et évitez de définir cette valeur sur les ressources statiques publiques.
* (caractère générique)
La valeur générique signale que la réponse varie selon des facteurs qui ne sont capturés par aucun en-tête de requête. Les caches la traitent comme non cacheable. Rarement utilisée intentionnellement.
Exemple
Un serveur compresse les réponses en utilisant l’encodage demandé par le client. L’en-tête Vary: Accept-Encoding indique aux caches intermédiaires de stocker des copies distinctes pour les requêtes gzip et Brotli, plutôt que de servir une réponse compressée en gzip à un client capable de gérer Brotli.
Vary: Accept-Encoding
Une configuration de négociation de contenu délivre du JSON ou du HTML depuis le même point de terminaison. Le cache stocke des réponses distinctes selon la valeur de l’en-tête Accept.
Vary: Accept
Les différents en-têtes qui influencent la réponse sont listés dans une valeur séparée par des virgules. Ici, la réponse dépend à la fois de l’encodage accepté et de la langue préférée.
Vary: Accept-Encoding, Accept-Language
Une configuration de diffusion dynamique délivre un HTML différent aux agents utilisateurs mobiles et de bureau. Le cache stocke des versions distinctes indexées par la chaîne User-Agent complète.
Vary: User-Agent
Associer Vary à Cache-Control permet de contrôler à la fois ce qui varie et la durée de fraîcheur de chaque variante.
Cache-Control: public, max-age=3600
Vary: Accept-Encoding
Dépannage
Les problèmes de mise en cache causés par un en-tête Vary absent ou trop large se manifestent souvent par des utilisateurs qui reçoivent un contenu erroné.
Le CDN sert la mauvaise variante mise en cache. Un serveur renvoie un contenu différent selon un en-tête de requête mais omet la valeur Vary correspondante. Le CDN met en cache la première réponse et sert la même copie à tous les clients, quels que soient leurs en-têtes de requête. Ajoutez le nom de l’en-tête concerné à la liste Vary. Testez en envoyant des requêtes avec des valeurs d’en-tête différentes via curl et en comparant les en-têtes de réponse X-Cache ou Age : curl -H “Accept-Encoding: gzip” -v https://cdn.example.re/style.css curl -H “Accept-Encoding: br” -v https://cdn.example.re/style.css
Fragmentation du cache due à Vary: User-Agent. La chaîne User-Agent possède des milliers de valeurs uniques. Lister User-Agent dans l’en-tête Vary crée une entrée de cache distincte pour presque chaque visiteur, ce qui détruit le taux de succès du cache. Des CDN comme Cloudflare et Fastly normalisent le User-Agent en classes d’appareils. Dans la mesure du possible, utilisez un en-tête normalisé tel que Sec-CH-UA-Mobile ou un en-tête de type d’appareil propre au CDN plutôt que le User-Agent brut.
Vary: * désactive complètement la mise en cache. Le caractère générique indique aux caches que la réponse varie selon des facteurs extérieurs à tout en-tête de requête. La plupart des caches la traitent comme non cacheable et ne servent jamais de copie stockée. Supprimez Vary: * sauf si l’intention est de désactiver toute mise en cache pour la ressource. Si un en-tête de requête précis est à l’origine de la variation, nommez cet en-tête explicitement.
L’absence de Vary: Origin provoque un empoisonnement de cache CORS. Un serveur renvoie une valeur Access-Control-Allow-Origin dynamique basée sur l’en-tête de requête Origin mais n’inclut pas Vary: Origin. Un CDN met la réponse en cache avec une origine et sert le même en-tête CORS à une autre origine, ce qui amène les navigateurs à bloquer la réponse. Ajoutez Vary: Origin à chaque réponse qui reflète une valeur d’origine dynamique. Pour diagnostiquer, envoyez deux requêtes curl depuis des origines différentes et vérifiez si la valeur Access-Control-Allow-Origin mise en cache change : curl -H “Origin: https://a.example.re” -v https://api.example.re/data curl -H “Origin: https://b.example.re” -v https://api.example.re/data
Incohérences de Vary: Accept-Encoding entre gzip et Brotli. Certains serveurs d’origine compressent en gzip alors qu’un nœud de périphérie du CDN recompresse en Brotli, ce qui crée un décalage entre l’encodage mis en cache et la clé Vary. Assurez-vous que le serveur d’origine et le CDN s’accordent sur le comportement d’encodage. Dans nginx, définissez gzip_vary on; pour ajouter automatiquement Vary: Accept-Encoding. Lorsque vous utilisez Brotli en plus de gzip, vérifiez que les deux modules ajoutent la même valeur Vary afin que le cache stocke des entrées distinctes par encodage.