ETag : définition, mécanisme de cache et configuration de l'en-tête

Auteur : IT Sectr Publié le : 2026-03-09 Temps de lecture : 8 min

ETag (Entity Tag) est un en-tête HTTP qui attribue un identifiant unique à une version de ressource sur le serveur, permettant au client de vérifier efficacement la pertinence des données mises en cache. Lors d'une requête répétée, le navigateur ou l'application envoie l'ETag sauvegardé, et le serveur le compare à l'actuel : en cas de correspondance, il retourne un statut 304 Not Modified sans corps de réponse. Selon la RFC 7232 (IETF, 2014), les requêtes conditionnelles avec ETag réduisent le volume de données transférées jusqu'à 95 % pour les ressources fréquemment demandées. Cela rend cet en-tête critique pour les performances des applications mobiles.

Points clés

  • ETag — un en-tête HTTP avec un identifiant unique de version de ressource pour les requêtes conditionnelles et la mise en cache
  • Fonctionnement — le serveur génère un hash du contenu ou un numéro de version, le client l'envoie dans l'en-tête If-None-Match
  • ETags forts et faibles — forts (contenu identique octet par octet) et faibles (contenu sémantiquement équivalent, préfixe W/)
  • 304 Not Modified — réponse du serveur en cas de correspondance ETag, économisant le trafic et accélérant le chargement
  • ETag vs Last-Modified — ETag est plus précis (hash du contenu), Last-Modified est plus simple (date), ensemble ils offrent une efficacité maximale

Qu'est-ce que ETag ?

ETag (Entity Tag) est un en-tête de réponse HTTP contenant un identifiant unique pour une version spécifique d'une ressource. Le serveur calcule l'ETag en fonction du contenu du fichier, de ses métadonnées ou du numéro de révision et l'envoie au client dans la réponse à une requête GET. Le client sauvegarde cet identifiant et lors de requêtes ultérieures à la même ressource, l'envoie dans l'en-tête If-None-Match. Si la ressource n'a pas changé, le serveur répond avec 304 Not Modified et le client utilise sa copie en cache.

Le format ETag est défini dans la RFC 7232 comme une chaîne entre guillemets : "33a64df551425fcc55e4d42a148795d9f25f89d4". La valeur peut être un hash SHA-1 du contenu du fichier, un numéro de version incrémental, une combinaison inode-numéro-temps pour les fichiers statiques ou un jeton arbitraire généré par le serveur. La seule exigence est que la valeur doit changer lorsque la ressource change et ne doit pas changer si la ressource reste identique.

ETag appartient aux mécanismes de requêtes conditionnelles (conditional requests) — l'une des optimisations de base du protocole HTTP. Contrairement aux requêtes inconditionnelles où le serveur retourne toujours une réponse complète, une requête conditionnelle permet au client de vérifier la pertinence du cache sans recharger les données. Selon HTTP Archive (2025), environ 40 % de toutes les réponses HTTP sont des 304 Not Modified grâce à une configuration appropriée d'ETag et de Last-Modified.

Où ETag est utilisé

ETag est utilisé dans les API REST pour optimiser le chargement des collections de données — si la liste d'objets n'a pas changé, le client reçoit 304 sans transférer tout le JSON. Pour les fichiers statiques (CSS, JS, images), ETag permet aux CDN et aux navigateurs de vérifier efficacement la fraîcheur du cache. Dans les applications mobiles, ETag est essentiel pour la synchronisation en arrière-plan : l'application vérifie si les données sur le serveur ont changé et télécharge les mises à jour uniquement si nécessaire. Cela économise le trafic et la batterie de l'appareil.

Comment fonctionne ETag ?

Le cycle de vie complet d'ETag se compose de quatre étapes. Le serveur génère un ETag lors de la première requête et le retourne dans l'en-tête de réponse. Le client sauvegarde l'ETag avec la ressource mise en cache. Lors d'une requête répétée, le client envoie l'en-tête If-None-Match avec la valeur de l'ETag sauvegardé. Le server compare la valeur reçue avec l'ETag actuel de la ressource : en cas de correspondance, il retourne 304 Not Modified avec un corps vide; en cas de non-correspondance, il retourne 200 OK avec la nouvelle ressource et un nouvel ETag.

http
// Requête client avec If-None-Match
GET /api/users HTTP/1.1
Host: example.com
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

// Réponse du serveur — ressource inchangée
HTTP/1.1 304 Not Modified
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Dans une application mobile, ce cycle peut être implémenté via un client HTTP avec support de cache. OkHttp, par exemple, gère automatiquement l'ETag via CacheInterceptor : il sauvegarde l'ETag de réponse et ajoute If-None-Match lors des requêtes répétées. En recevant 304, OkHttp retourne les données en cache. OkHttp supporte ETag sans configuration supplémentaire — il suffit d'activer le cache via OkHttpClient.Builder.cache().

Génération d'ETag côté serveur

Le serveur peut calculer les ETags de différentes manières : via un hash MD5 ou SHA du contenu, via un numéro de révision de la base de données (par exemple, updated_at de MySQL), via une combinaison d'inode + mtime + taille pour les fichiers statiques (Nginx génère les ETags exactement de cette façon). Pour les API dynamiques, le hash du contenu est le plus fiable : si la réponse JSON change ne serait-ce qu'un champ, l'ETag changera. Cependant, calculer un hash à chaque requête sollicite le CPU — pour les systèmes à forte charge, il est préférable d'utiliser un numéro de version incrémental.

ETags forts et faibles

La RFC 7232 définit deux types d'ETags : forts (strong) et faibles (weak). Un ETag fort signifie que deux représentations de la ressource sont identiques octet par octet — pas un seul bit ne diffère. Un ETag faible (préfixe W/) ne garantit qu'une équivalence sémantique : le contenu peut différer au niveau de la sérialisation (espaces, ordre des champs JSON), mais les données sont considérées comme identiques pour le client. Les ETags faibles sont marqués par le préfixe W/, par exemple W/"1a2b3c".

Le choix du type d'ETag dépend des exigences de précision de la comparaison. Pour les fichiers statiques (CSS, JS, images), les ETags forts sont préférables — si le fichier a changé, le client doit obtenir la nouvelle version. Pour les API dynamiques, où le même JSON peut être sérialisé avec un ordre de champs ou un formatage différent, les ETags faibles offrent plus de flexibilité : le serveur génère l'ETag en fonction des données métier, et non de la représentation textuelle.

Type d'ETagFormatGarantieApplication
Strong (fort)"hash"Identité octet par octetFichiers statiques, ressources binaires
Weak (faible)W/"hash"Équivalence sémantiqueAPI JSON, pages dynamiques

Une limitation des ETags faibles : ils ne peuvent pas être utilisés avec les requêtes de plage (Range requests). Si le client demande une partie d'un fichier, le serveur doit retourner un ETag fort pour garantir que le fragment correspond à la ressource complète. Les ETags faibles n'offrent pas cette garantie. Dans d'autres scénarios, les ETags faibles sont sûrs et recommandés pour les API.

ETag vs Last-Modified

ETag et Last-Modified sont deux en-têtes HTTP pour les requêtes conditionnelles qui sont souvent utilisés ensemble. Last-Modified indique la date de dernière modification d'une ressource et fonctionne avec l'en-tête If-Modified-Since. ETag fournit un identifiant de version unique et fonctionne avec If-None-Match. Chacun a ses avantages et ses limites, et les combiner offre une efficacité de cache maximale.

Last-Modified est plus simple à implémenter — le serveur obtient automatiquement la date du système de fichiers ou met à jour le champ updated_at dans la base de données. Cependant, la date a une précision à la seconde, ce qui est insuffisant pour les ressources qui changent plusieurs fois par seconde. De plus, Last-Modified ne distingue pas les différents états : si un fichier est écrasé avec la même version, la date change mais le contenu ne change pas, donc le client rechargera des données identiques.

ETag est plus précis : il change uniquement lorsque le contenu change réellement. Si le serveur restaure une version antérieure à partir d'une sauvegarde, l'ETag change. Si un fichier est écrasé avec les mêmes données, l'ETag reste identique et le client ne recharge pas. L'utilisation combinée est recommandée par la spécification HTTP : le serveur retourne les deux en-têtes, le client envoie If-None-Match et If-Modified-Since simultanément. Si au moins un en-tête indique un changement, le serveur retourne une nouvelle ressource.

Priorité des en-têtes

Selon la spécification, ETag a priorité sur Last-Modified. Si le serveur reçoit If-None-Match, il doit vérifier uniquement l'ETag, en ignorant If-Modified-Since. Cela évite les conditions de course : si la ressource change entre l'envoi de Last-Modified par le client et la vérification sur le serveur, ETag sera l'indicateur le plus récent. En pratique, les serveurs vérifient généralement les deux en-têtes, mais en cas de non-concordance des résultats, ETag l'emporte.

Implémentation d'ETag côté serveur

La configuration d'ETag dépend du type de serveur. Nginx génère les ETags pour les fichiers statiques automatiquement en fonction de l'inode, mtime et de la taille. Apache utilise le mécanisme FileETag. Pour les applications dynamiques sur Node.js, PHP, Python, Ruby, les ETags doivent être générés programmatiquement — via un hash de réponse, un numéro de version des données ou une combinaison de paramètres de requête.

go
func etagMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter,
        r *http.Request) {
        // Génération d'ETag basée sur les données
        etag := generateETag(r.URL.Path)
        w.Header().Set("ETag", etag)

        // Vérification If-None-Match
        if r.Header.Get("If-None-Match") == etag {
            w.WriteHeader(http.StatusNotModified)
            return
        }
        next.ServeHTTP(w, r)
    })
}

Un middleware en Go intercepte la requête, génère un ETag pour l'URL demandée (par exemple, calcule un hash des données à partir du cache ou de la BD) et définit l'en-tête de réponse. Si le client a envoyé If-None-Match et qu'il correspond à l'ETag actuel, le serveur retourne immédiatement 304 Not Modified, sans appeler le gestionnaire principal. En production, il convient d'ajouter une mise en cache des ETags calculés par URL et paramètres pour réduire la charge du serveur.

Problèmes et pièges

Dans une configuration multi-serveurs (round-robin ou anycast), l'ETag doit être le même sur tous les nœuds pour la même ressource. Si l'ETag est généré en fonction de l'inode du fichier et que le site est déployé sur plusieurs serveurs, les valeurs seront différentes. La solution est d'utiliser un hash du contenu ou un stockage centralisé des versions (Redis, etcd). Le deuxième problème est la compression gzip : Nginx modifie l'ETag lorsque la compression est activée, ce qui peut provoquer des réponses 304 redondantes. Il est nécessaire de configurer gzip_vary on pour synchroniser l'ETag avec le contenu compressé.

Questions fréquentes

L'ETag peut-il être identique pour différentes ressources ?

Oui, si le serveur ne l'a pas explicitement empêché. Un ETag n'a pas besoin d'être globalement unique — il est unique dans une URL spécifique. Pour les fichiers statiques, les collisions sont improbables lors de l'utilisation d'un hash SHA, mais les générateurs personnalisés peuvent produire des doublons.

Dois-je configurer ETag pour chaque ressource ?

ETag est le plus efficace pour les ressources qui sont demandées répétément et qui changent rarement : actifs statiques, listes d'API, configurations. Pour les pages uniques chargées une seule fois (par exemple, une page de confirmation de commande), ETag n'apporte aucun avantage.

Comment ETag fonctionne-t-il avec un CDN ?

Les CDN prennent en compte l'ETag dans les requêtes d'origine pour vérifier la fraîcheur du cache. Si l'ETag d'une ressource sur l'origine a changé, le CDN charge la nouvelle version. Cloudflare et Fastly prennent en charge ETag comme mécanisme standard d'invalidation de cache au niveau de l'origine.

Un ETag peut-il dépasser 255 caractères ?

La RFC 7232 ne limite pas la longueur de l'ETag, mais les serveurs et les proxies peuvent tronquer ou ignorer les valeurs trop longues. Il est recommandé d'utiliser un hash de 20 à 40 caractères ou une combinaison d'identifiant de version et de somme de contrôle.

Que choisir : ETag ou Cache-Control ?

Ce ne sont pas des mécanismes mutuellement exclusifs. Cache-Control définit la politique de cache (durée de conservation, qui est autorisé), tandis qu'ETag est un mécanisme de validation des ressources en cache. La configuration optimale inclut les deux en-têtes ensemble.

Résumé

  • ETag — un en-tête HTTP avec un identifiant unique de version de ressource pour les requêtes conditionnelles et une mise en cache efficace
  • Principe — le client envoie If-None-Match avec l'ETag sauvegardé, le serveur répond avec 304 en cas de correspondance
  • ETags forts — identité octet par octet pour les fichiers statiques, faibles — équivalence sémantique pour les API
  • ETag est plus précis que Last-Modified — il suit le contenu, pas la date, et change uniquement lors de modifications réelles
  • Utilisation combinée avec Last-Modified offre une efficacité de cache maximale
  • Côté serveur — génération via hash du contenu, numéro de version des données ou combinaison de paramètres
  • Recommandation — utiliser ETag pour tous les points de terminaison d'API et ressources statiques dans les applications mobiles

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi