ETag (Entity Tag) — egy HTTP fejléc, amely egyedi azonosítót rendel a szerveren lévő erőforrás verziójához, lehetővé téve az ügyfél számára a gyorsítótárba helyezett adatok aktualitásának hatékony ellenőrzését. Ismételt kérésnél a böngésző vagy alkalmazás elküldi a mentett ETag-et, és a szerver összehasonlítja azt a jelenlegivel: egyezés esetén a 304 Not Modified állapot kerül visszaküldésre választörzs nélkül. Az RFC 7232 (IETF, 2014) szerint a feltételes kérések ETag-gal akár 95%-kal is csökkentik az átviteli adatok mennyiségét a gyakran kért erőforrások esetén. Ez a fejlécet kritikussá teszi a mobilalkalmazások teljesítménye szempontjából.
Főbb pontok
ETag (Entity Tag) — egy HTTP válasz fejléc, amely egy adott erőforrásverzió egyedi azonosítóját tartalmazza. A szerver az ETag-et a fájl tartalma, metaadatai vagy revíziószáma alapján számolja ki, és továbbítja az ügyfélnek a GET kérésre adott válaszban. Az ügyfél elmenti ezt az azonosítót, és a következő, ugyanazon erőforrásra irányuló kéréseknél elküldi azt az If-None-Match fejlécben. Ha az erőforrás nem változott, a szerver 304 Not Modified válasszal válaszol, és az ügyfél a saját gyorsítótárba helyezett másolatát használja.
Az ETag formátuma az RFC 7232-ben idézőjelek közötti karakterként van meghatározva: "33a64df551425fcc55e4d42a148795d9f25f89d4". Az érték lehet a fájl tartalmának SHA-1 hash-je, egy növekvő verziószám, egy inode-szám-idő kombináció statikus fájlokhoz, vagy a szerver által generált tetszőleges token. Az egyetlen követelmény, hogy az érték változzon az erőforrás minden módosításakor, és ne változzon, ha az erőforrás ugyanaz marad.
Az ETag a feltételes kérések (conditional requests) mechanizmusába tartozik — a HTTP protokoll egyik alapvető optimalizálásába. Ellentétben a feltétel nélküli kérésekkel, ahol a szerver mindig teljes választ küld vissza, a feltételes kérés lehetővé teszi az ügyfél számára a gyorsítótár aktualitásának ellenőrzését az adatok újratöltése nélkül. A HTTP Archive (2025) adatai szerint az összes HTTP válasz körülbelül 40%-a 304 Not Modified az ETag és a Last-Modified helyes beállításának köszönhetően.
Az ETag-et a REST API-ban használják az adatgyűjtemények betöltésének optimalizálására — ha az objektumok listája nem változott, az ügyfél 304-et kap a teljes JSON elküldése nélkül. Statikus fájlokban (CSS, JS, képek) az ETag lehetővé teszi a CDN-ök és böngészők számára a gyorsítótár aktualitásának hatékony ellenőrzését. Mobilalkalmazásokban az ETag kritikus a háttérszinkronizációhoz: az alkalmazás ellenőrzi, hogy változtak-e az adatok a szerveren, és csak szükség esetén tölti le a frissítéseket. Ez sávszélességet és akkumulátort takarít meg.
Az ETag teljes működési ciklusa négy lépésből áll. A szerver az első kérésnél létrehozza az ETag-et, és visszaküldi azt a válasz fejlécében. Az ügyfél elmenti az ETag-et a gyorsítótárba helyezett erőforrással együtt. Ismételt kérésnél az ügyfél elküldi az If-None-Match fejlécet a mentett ETag értékével. A szerver összehasonlítja a kapott értéket az erőforrás aktuális ETag-jével: egyezés esetén 304 Not Modified-t küld ürüs törzssel, eltérés esetén — 200 OK-t új erőforrással és új ETag-gel.
// Ügyfél kérése If-None-Match-gal
GET /api/users HTTP/1.1
Host: example.com
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
// Szerver válasz — az erőforrás nem változott
HTTP/1.1 304 Not Modified
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Egy mobilalkalmazásban ez a ciklus megvalósítható HTTP kliensen keresztül gyorsítótár támogatással. Az OkHttp például automatikusan kezeli az ETag-et a CacheInterceptor-on keresztül: elmenti a válasz ETag-jét, és ismételt kérésnél hozzáadja az If-None-Match-ot. 304-es válasz vételén az OkHttp visszaadja a gyorsítótárba helyezett adatokat. Az OkHttp támogatja az ETag-et külön konfiguráció nélkül — elég a gyorsítótár bekapcsolása az OkHttpClient.Builder.cache()-en keresztül.
A szerver különböző módokon számolhatja ki az ETag-et: a tartalom MD5 vagy SHA hash-jén keresztül, az adatbázisból származó revíziószámon keresztül (például updated_at a MySQL-ből), az inode + mtime + size kombinációján keresztül statikus fájlokhoz (az Nginx pontosan így generál ETag-et). Dinamikus API-k esetén a legmegbízhatóbb a tartalom hash-je: ha a JSON válasz akár egy mezőt is módosított, az ETag megváltozik. A hash minden egyes kérésnél történő kiszámítása azonban terheli a processzort — a nagy terhelésű rendszerekhez jobb növekvő verziószámot használni.
Az RFC 7232 két típusú ETag-et határoz meg: erős (strong) és gyenge (weak). Az erős ETag azt jelenti, hogy az erőforrás két reprezentációja bájt-bájtra azonos — egyetlen bit sem különbözik. A gyenge ETag (W/ előtag) csak szemantikai egyenértékűséget garantál: a tartalom eltérhet a szerializáció szintjén (szóközök, JSON mezők sorrendje), de az adatok az ügyfél számára azonosnak minősülnek. A gyenge ETag-ek W/ előtaggal vannak jelölve, például W/"1a2b3c".
Az ETag típusának kiválasztása az összehasonlítás pontossági követelményeitől függ. Statikus fájlokhoz (CSS, JS, képek) az erős ETag-ek előnyösebbek — ha a fájl megváltozott, az ügyfélnek új verziót kell kapnia. Dinamikus API-khoz, ahol ugyanaz a JSON eltérő mezősorrenddel vagy formázással szerializálható, a gyenge ETag-ek nagyobb rugalmasságot biztosítanak: a szerver az ETag-et üzleti adatok alapján generálja, nem a string reprezentáció alapján.
| ETag típus | Formátum | Garancia | Alkalmazás |
|---|---|---|---|
| Strong (erős) | "hash" | Bájt-bájtra azonosság | Statikus fájlok, bináris erőforrások |
| Weak (gyenge) | W/"hash" | Szemantikai egyenértékűség | JSON API, dinamikus oldalak |
A gyenge ETag-ek korlátozása: nem használhatók tartománykérésekkel (Range requests). Ha az ügyfél a fájl egy részét kéri, a szervernek erős ETag-et kell visszaküldenie annak garantálására, hogy a töredék megfelel a teljes erőforrásnak. A gyenge ETag-ek nem nyújtanak ilyen garanciát. Más forgatókönyvekben a gyenge ETag-ek biztonságosak és ajánlottak API-khoz.
Az ETag és a Last-Modified két HTTP fejléc a feltételes kérésekhez, amelyeket gyakran használnak együtt. A Last-Modified az erőforrás utolsó módosításának dátumát jelzi, és az If-Modified-Since fejléccel működik. Az ETag egyedi verzióazonosítót biztosít, és az If-None-Match fejléccel működik. Mindegyiknek megvannak a maga előnyei és korlátozásai, a kombináció pedig maximális gyorsítótári hatékonyságot nyújt.
A Last-Modified egyszerűbben megvalósítható — a szerver automatikusan lekéri a dátumot a fájlrendszerből, vagy frissíti az updated_at mezőt az adatbázisban. A dátum pontossága azonban másodpercig terjed, ami nem elegendő a másodpercenként többször változó erőforrásokhoz. Emellett a Last-Modified nem különbözteti meg a különböző állapotokat: ha a fájlt ugyanazzal a verzióval írják felül, a dátum változik, de a tartalom nem — az ügyfél újratölti az azonos adatokat.
Az ETag pontosabb: csak a tartalom tényleges megváltozásakor változik. Ha a szerver visszaállította az előző verziót a biztonsági mentésből, az ETag megváltozik. Ha a fájlt ugyanazokkal az adatokkal írják felül — az ETag ugyanaz marad, és az ügyfél nem tölti újra. A közös használatot a HTTP specifikáció ajánlja: a szerver mindkét fejlécet visszaküldi, az ügyfél egyszerre küldi el az If-None-Match és If-Modified-Since fejléceket. Ha legalább az egyik fejléc változást jelez — a szerver új erőforrást küld vissza.
A specifikáció szerint az ETag elsőbbséget élvez a Last-Modified-dal szemben. Ha a szerver If-None-Match-ot kapott, csak az ETag-et kell ellenőriznie, figyelmen kívül hagyva az If-Modified-Since-t. Ez megakadályozza a race condition-t: ha az erőforrás megváltozott az ügyfél által küldött Last-Modified és a szerveren történő ellenőrzés között, az ETag frissebb mutató lesz. A gyakorlatban a szerverek általában mindkét fejlécet ellenőrzik, de eltérő eredmények esetén az ETag nyer.
Az ETag konfigurálása a szerver típusától függ. Az Nginx automatikusan generál ETag-et a statikus fájlokhoz az inode, mtime és méret alapján. Az Apache a FileETag mechanizmust használja. Dinamikus alkalmazásokhoz Node.js, PHP, Python, Ruby környezetben az ETag-et programozottan kell generálni — a válasz hash-je, az adatok verziószáma vagy a kérés paramétereinek kombinációja révén.
func etagMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter,
r *http.Request) {
// ETag generálása adatok alapján
etag := generateETag(r.URL.Path)
w.Header().Set("ETag", etag)
// If-None-Match ellenőrzése
if r.Header.Get("If-None-Match") == etag {
w.WriteHeader(http.StatusNotModified)
return
}
next.ServeHTTP(w, r)
})
}
A Go middleware elfogja a kérést, ETag-et generál a kért URL-hez (például kiszámítja a gyorsítótárból vagy adatbázisból származó adatok hash-jét), és beállítja a válasz fejlécét. Ha az ügyfél If-None-Match-ot küldött, és az megegyezik az aktuális ETag-gel, a szerver azonnal 304 Not Modified választ küld, a fő handler meghívása nélkül. Éles környezetben érdemes hozzáadni a kiszámított ETag-ek gyorsítótárazását URL és paraméterek szerint a szerver terhelésének csökkentése érdekében.
Többszerveres konfigurációban (round-robin vagy anycast) az ETag-nek azonosnak kell lennie minden csomóponton ugyanazon erőforrás esetén. Ha az ETag a fájl inode-ja alapján generálódik, és a weboldal több szerveren fut, az értékek eltérőek lesznek. Megoldás — tartalom hash vagy központosított verziótárolás (Redis, etcd) használata. A második probléma — gzip tömörítés: az Nginx megváltoztatja az ETag-et a tömörítés bekapcsolásakor, ami túlzott 304-es válaszokat okozhat. Az ETag és a tömörített tartalom szinkronizálásához a gzip_vary on beállítása szükséges.
Gyakran ismételt kérdések
Igen, ha a szerver ezt nem akadályozta meg kifejezetten. Az ETag-nek nem kell globálisan egyedinek lennie — egy adott URL-en belül egyedi. Statikus fájlok esetén az ütközések nem valószínűek SHA hash használatakor, de házi készítésű generátoroknál előfordulhatnak duplikátumok.
Az ETag a leginkább azoknál az erőforrásoknál hatékony, amelyeket többször kérnek és ritkán változnak: statikus fájlok, API listák, konfigurációk. Az egyedi oldalaknál, amelyek egyszer töltődnek be (például rendelés visszaigazoló oldal), az ETag nem nyújt előnyt.
A CDN figyelembe veszi az ETag-et az origin kérésekben a gyorsítótár aktualitásának ellenőrzéséhez. Ha az erőforrás ETag-je az origin-en megváltozott, a CDN letölti az új verziót. A Cloudflare és a Fastly az ETag-et a gyorsítótár érvénytelenítésének szabványos mechanizmusaként támogatja az origin szintjén.
Az RFC 7232 nem korlátozza az ETag hosszát, de a szerverek és proxyk leróvidíthetik vagy figyelmen kívül hagyhatják a túl hosszú értékeket. Javasolt 20–40 karakter hosszúságú hash vagy verzióazonosító és ellenőrzőösszeg kombinációjának használata.
Ezek nem egymást kizáró mechanizmusok. A Cache-Control határozza meg a gyorsítótári politikát (mennyi ideig tároljon, kinek engedélyezett), az ETag pedig a gyorsítótárba helyezett erőforrás érvényesítési mechanizmusa. Az optimális konfiguráció mindkét fejlécet együtt tartalmazza.
Összefoglaló
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is