ETag: cos'è, meccanismo di caching e configurazione dell'intestazione

Autore: IT Sectr Pubblicato: 2026-03-09 Tempo di lettura: 8 min

ETag (Entity Tag) è un'intestazione HTTP che assegna un identificatore univoco a una versione di risorsa sul server, consentendo al client di verificare in modo efficiente la pertinenza dei dati memorizzati nella cache. In una richiesta ripetuta, il browser o l'applicazione invia l'ETag salvato e il server lo confronta con quello corrente: in caso di corrispondenza, restituisce uno stato 304 Not Modified senza corpo della risposta. Secondo la RFC 7232 (IETF, 2014), le richieste condizionali con ETag riducono il volume di dati trasferiti fino al 95% per le risorse richieste frequentemente. Ciò rende l'intestazione estremamente importante per le prestazioni delle applicazioni mobili.

Punti chiave

  • ETag — un'intestazione HTTP con un identificatore univoco di versione della risorsa per richieste condizionali e caching
  • Come funziona — il server genera un hash del contenuto o un numero di versione, il client lo invia nell'intestazione If-None-Match
  • ETag forti e deboli — forti (contenuto identico byte per byte) e deboli (contenuto semanticamente equivalente, prefisso W/)
  • 304 Not Modified — risposta del server in caso di corrispondenza ETag, risparmiando traffico e accelerando il caricamento
  • ETag vs Last-Modified — ETag è più preciso (hash del contenuto), Last-Modified è più semplice (data), insieme offrono la massima efficienza

Cos'è ETag?

ETag (Entity Tag) è un'intestazione di risposta HTTP contenente un identificatore univoco per una versione specifica di una risorsa. Il server calcola l'ETag in base al contenuto del file, ai suoi metadati o al numero di revisione e lo invia al client nella risposta a una richiesta GET. Il client salva questo identificatore e nelle richieste successive alla stessa risorsa lo invia nell'intestazione If-None-Match. Se la risorsa non è cambiata, il server risponde con 304 Not Modified e il client utilizza la sua copia memorizzata nella cache.

Il formato ETag è definito nella RFC 7232 come una stringa tra virgolette: "33a64df551425fcc55e4d42a148795d9f25f89d4". Il valore può essere un hash SHA-1 del contenuto del file, un numero di versione incrementale, una combinazione di inode-numero-tempo per file statici o un token arbitrario generato dal server. L'unico requisito è che il valore deve cambiare quando la risorsa cambia e non deve cambiare se la risorsa rimane invariata.

ETag appartiene ai meccanismi di richiesta condizionale (conditional requests) — una delle ottimizzazioni di base del protocollo HTTP. A differenza delle richieste incondizionate, dove il server restituisce sempre una risposta completa, una richiesta condizionale consente al client di verificare la pertinenza della cache senza ricaricare i dati. Secondo HTTP Archive (2025), circa il 40% di tutte le risposte HTTP sono 304 Not Modified grazie alla corretta configurazione di ETag e Last-Modified.

Dove viene utilizzato ETag

ETag viene utilizzato nelle API REST per ottimizzare il caricamento delle collezioni di dati — se l'elenco degli oggetti non è cambiato, il client riceve 304 senza trasferire l'intero JSON. Per i file statici (CSS, JS, immagini), ETag consente a CDN e browser di verificare in modo efficiente la freschezza della cache. Nelle applicazioni mobili, ETag è fondamentale per la sincronizzazione in background: l'app verifica se i dati sul server sono cambiati e scarica gli aggiornamenti solo quando necessario. Ciò risparmia traffico e batteria del dispositivo.

Come funziona ETag?

Il ciclo di vita completo di ETag consiste in quattro fasi. Il server genera un ETag alla prima richiesta e lo restituisce nell'intestazione di risposta. Il client salva l'ETag insieme alla risorsa memorizzata nella cache. In una richiesta ripetuta, il client invia l'intestazione If-None-Match con il valore dell'ETag salvato. Il server confronta il valore ricevuto con l'ETag corrente della risorsa: in caso di corrispondenza, restituisce 304 Not Modified con corpo vuoto; in caso di mancata corrispondenza, restituisce 200 OK con la nuova risorsa e un nuovo ETag.

http
// Richiesta client con If-None-Match
GET /api/users HTTP/1.1
Host: example.com
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

// Risposta del server — risorsa non modificata
HTTP/1.1 304 Not Modified
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

In un'applicazione mobile, questo ciclo può essere implementato tramite un client HTTP con supporto per la cache. OkHttp, ad esempio, gestisce automaticamente ETag tramite CacheInterceptor: salva l'ETag della risposta e aggiunge If-None-Match nelle richieste ripetute. Quando riceve 304, OkHttp restituisce i dati memorizzati nella cache. OkHttp supporta ETag senza configurazione aggiuntiva — basta abilitare la cache tramite OkHttpClient.Builder.cache().

Generazione di ETag lato server

Il server può calcolare gli ETag in diversi modi: tramite hash MD5 o SHA del contenuto, tramite un numero di revisione dal database (ad esempio, updated_at da MySQL), tramite una combinazione di inode + mtime + dimensione per file statici (Nginx genera ETag esattamente in questo modo). Per le API dinamiche, l'hash del contenuto è il più affidabile: se la risposta JSON cambia anche solo un campo, l'ETag cambierà. Tuttavia, calcolare un hash ad ogni richiesta carica la CPU — per i sistemi ad alto carico, è meglio utilizzare un numero di versione incrementale.

ETag forti e deboli

RFC 7232 definisce due tipi di ETag: forti (strong) e deboli (weak). Un ETag forte significa che due rappresentazioni della risorsa sono identiche byte per byte — nessun singolo bit differisce. Un ETag debole (prefisso W/) garantisce solo equivalenza semantica: il contenuto può differire a livello di serializzazione (spazi, ordine dei campi JSON), ma i dati sono considerati uguali per il client. Gli ETag deboli sono contrassegnati dal prefisso W/, ad esempio W/"1a2b3c".

La scelta del tipo di ETag dipende dai requisiti di precisione del confronto. Per i file statici (CSS, JS, immagini), ETag forti sono preferibili — se il file è cambiato, il client deve ottenere la nuova versione. Per le API dinamiche, dove lo stesso JSON può essere serializzato con un ordine dei campi o una formattazione diversi, gli ETag deboli offrono maggiore flessibilità: il server genera l'ETag in base ai dati aziendali, non alla rappresentazione testuale.

Tipo di ETagFormatoGaranziaApplicazione
Strong (forte)"hash"Identità byte per byteFile statici, risorse binarie
Weak (debole)W/"hash"Equivalenza semanticaAPI JSON, pagine dinamiche

Una limitazione degli ETag deboli: non possono essere utilizzati con le richieste di intervallo (Range requests). Se il client richiede una parte di un file, il server deve restituire un ETag forte per garantire che il frammento corrisponda alla risorsa completa. Gli ETag deboli non forniscono tale garanzia. In altri scenari, gli ETag deboli sono sicuri e consigliati per le API.

ETag vs Last-Modified

ETag e Last-Modified sono due intestazioni HTTP per richieste condizionali che vengono spesso utilizzate insieme. Last-Modified indica la data dell'ultima modifica di una risorsa e funziona con l'intestazione If-Modified-Since. ETag fornisce un identificatore univoco di versione e funziona con If-None-Match. Ognuno ha i suoi vantaggi e limitazioni, e combinarli offre la massima efficienza di caching.

Last-Modified è più semplice da implementare — il server ottiene automaticamente la data dal filesystem o aggiorna il campo updated_at nel database. Tuttavia, la data ha una precisione al secondo, che è insufficiente per risorse che cambiano più volte al secondo. Inoltre, Last-Modified non distingue tra stati diversi: se un file viene sovrascritto con la stessa versione, la data cambia ma il contenuto no, quindi il client ricaricherà dati identici.

ETag è più preciso: cambia solo quando il contenuto cambia effettivamente. Se il server ripristina una versione precedente da un backup, l'ETag cambia. Se un file viene sovrascritto con gli stessi dati, l'ETag rimane invariato e il client non ricarica. L'uso combinato è raccomandato dalla specifica HTTP: il server restituisce entrambe le intestazioni, il client invia If-None-Match e If-Modified-Since simultaneamente. Se almeno un'intestazione indica un cambiamento, il server restituisce una nuova risorsa.

Priorità delle intestazioni

Secondo la specifica, ETag ha priorità su Last-Modified. Se il server riceve If-None-Match, deve verificare solo l'ETag, ignorando If-Modified-Since. Ciò previene le condizioni di competizione: se la risorsa cambia tra l'invio di Last-Modified da parte del client e la verifica sul server, ETag sarà l'indicatore più recente. In pratica, i server di solito verificano entrambe le intestazioni, ma in caso di mancata corrispondenza dei risultati, vince ETag.

Implementazione di ETag lato server

La configurazione di ETag dipende dal tipo di server. Nginx genera ETag per file statici automaticamente in base a inode, mtime e dimensione. Apache utilizza il meccanismo FileETag. Per applicazioni dinamiche su Node.js, PHP, Python, Ruby, gli ETag devono essere generati programmaticamente — tramite hash della risposta, numero di versione dei dati o combinazione di parametri di richiesta.

go
func etagMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter,
        r *http.Request) {
        // Generazione ETag basata sui dati
        etag := generateETag(r.URL.Path)
        w.Header().Set("ETag", etag)

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

Un middleware in Go intercetta la richiesta, genera un ETag per l'URL richiesto (ad esempio, calcola un hash dei dati dalla cache o dal DB) e imposta l'intestazione di risposta. Se il client ha inviato If-None-Match e corrisponde all'ETag corrente, il server restituisce immediatamente 304 Not Modified, senza chiamare il gestore principale. In produzione, è opportuno aggiungere la memorizzazione nella cache degli ETag calcolati per URL e parametri per ridurre il carico sul server.

Problemi e insidie

In una configurazione multi-server (round-robin o anycast), l'ETag deve essere lo stesso su tutti i nodi per la stessa risorsa. Se l'ETag viene generato in base all'inode del file e il sito è distribuito su più server, i valori differiranno. La soluzione è utilizzare un hash del contenuto o un archivio centralizzato delle versioni (Redis, etcd). Il secondo problema è la compressione gzip: Nginx modifica l'ETag quando la compressione è abilitata, il che può causare risposte 304 ridondanti. È necessario configurare gzip_vary on per sincronizzare l'ETag con il contenuto compresso.

Domande frequenti

L'ETag può essere lo stesso per risorse diverse?

Sì, se il server non lo ha esplicitamente impedito. Un ETag non deve essere globalmente univoco — è univoco all'interno di un URL specifico. Per i file statici, le collisioni sono improbabili quando si utilizza un hash SHA, ma i generatori personalizzati possono produrre duplicati.

Devo configurare ETag per ogni risorsa?

ETag è più efficace per le risorse che vengono richieste ripetutamente e raramente cambiano: asset statici, elenchi API, configurazioni. Per pagine uniche che vengono caricate una volta (ad esempio, una pagina di conferma dell'ordine), ETag non fornisce vantaggi.

Come funziona ETag con CDN?

I CDN considerano l'ETag nelle richieste all'origine per verificare la freschezza della cache. Se l'ETag di una risorsa sull'origine è cambiato, il CDN carica la nuova versione. Cloudflare e Fastly supportano ETag come meccanismo standard di invalidamento della cache a livello di origine.

Un ETag può essere più lungo di 255 caratteri?

RFC 7232 non limita la lunghezza dell'ETag, ma server e proxy possono troncare o ignorare valori eccessivamente lunghi. Si raccomanda di utilizzare un hash di 20–40 caratteri o una combinazione di identificatore di versione e checksum.

Cosa scegliere: ETag o Cache-Control?

Non sono meccanismi mutualmente esclusivi. Cache-Control definisce la politica di caching (quanto tempo memorizzare, chi è autorizzato), mentre ETag è un meccanismo di validazione per le risorse memorizzate nella cache. La configurazione ottimale include entrambe le intestazioni insieme.

Riepilogo

  • ETag — un'intestazione HTTP con un identificatore univoco di versione della risorsa per richieste condizionali e caching efficiente
  • Principio — il client invia If-None-Match con l'ETag salvato, il server risponde con 304 in caso di corrispondenza
  • ETag forti — identità byte per byte per file statici, deboli — equivalenza semantica per API
  • ETag è più preciso di Last-Modified — traccia il contenuto, non la data, e cambia solo con modifiche effettive
  • Uso combinato con Last-Modified offre la massima efficienza di caching
  • Lato server — generazione tramite hash del contenuto, numero di versione dei dati o combinazione di parametri
  • Raccomandazione — utilizzare ETag per tutti gli endpoint API e le risorse statiche nelle applicazioni mobili

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche