ETag — en HTTP-svarshuvud som innehåller en unik identifierare för resursversionen. Servern genererar ETag som en hash av innehållet eller versionsnummer och returnerar det till klienten tillsammans med data. Vid efterföljande förfrågningar skickar klienten denna identifierare i If-None-Match-huvudet, vilket gör att servern kan kontrollera om resursen har ändrats. Enligt MDN Web Docs, 2025 utgör ETag grunden för mekanismen för villkorliga GET-förfrågningar i HTTP. Villkorliga förfrågningar med ETag minskar mängden överförd data vid synkronisering av mobilappar med upp till 90%.
Huvudpunkter
ETag (Entity Tag) — HTTP-huvud från familjen villkorliga huvuden som tillhandahåller validering av cachade resurser. Servern beräknar ETag som en hashsumma (MD5, SHA-256) eller versionsnummer för resursen och returnerar den i svaret på en GET-förfrågan. Klienten sparar ETag tillsammans med data och vid nästa förfrågan skickar den i If-None-Match-huvudet. Om resursens innehåll inte har ändrats svarar servern med status 304 Not Modified utan svarskropp.
För mobilappar är ETag kritiskt eftersom det minskar mängden nedladdad data. Vid varje start eller synkronisering kontrollerar appen resursernas aktuellitet med en If-None-Match-förfrågan — istället för att ladda ner fullständig data får den 304 och använder den lokala kopian. Enligt Google Chrome Team (2024) minskar användningen av ETag i mobila API:er den genomsnittliga svarsvolymen med 87% för listor och med 94% för enskilda objekt.
ETag genereras på serversidan och kan vara både deterministisk (samma för samma innehåll, användbart för delade cacheminnen) och unik för varje svar (för strikt validering). I REST API:er avsedda för mobil synkronisering används oftast en kombination av innehållshash och versionsnummer för posten i databasen.
Stark ETag (strong ETag) — identifierare som ändras vid varje förändring av innehållet, inklusive mindre (mellanslag, formatering). Format: "abc123def" (inom citattecken, utan prefix). Starka ETag garanterar att resursen inte har ändrats byte för byte. De är obligatoriska för intervallförfrågningar (Range requests) och för kontroll av integriteten vid partiella nedladdningar.
Svag ETag (weak ETag) — identifierare med prefix W/, till exempel W/"abc123def". De tillåter att resursen är semantiskt ekvivalent, även om byte-representationen skiljer sig. Svaga ETag är användbara för servrar som dynamiskt genererar svar med olika mellanslag eller formatering men samma betydelse. Dock stöder svaga ETag inte intervallförfrågningar.
Jämförelse av ETag-typer:
| Egenskap | Stark ETag | Svag ETag |
|---|---|---|
| Format | "hash" | W/"hash" |
| Känslighet | Byte för byte | Semantisk |
| Intervallförfrågningar | Stöds | Stöds inte |
| CDN-cachning | Idealisk | Begränsad |
| Synkronisering | Hög precision | Tillåter kollisioner |
Last-Modified — HTTP-huvud som anger datum och tid för senaste ändringen av resursen. Klienten skickar tillbaka det i If-Modified-Since-huvudet. Last-Modified är enklare att implementera (servern behöver bara datum), men har fundamentala begränsningar: en sekunds upplösning (två ändringar inom en sekund går inte att särskilja) och oförmåga att avgöra om innehållet har ändrats vid samma tid (t.ex. efter återställning från backup).
ETag löser dessa problem: innehållshashen ändras vid varje förändring oberoende av tid. Därför använder moderna REST API:er en kombination av båda huvuden: ETag för exakt validering och Last-Modified för ungefärlig filtrering på CDN. Apache HTTP Server och Nginx genererar som standard båda huvudena för statiska filer.
För mobilappar med synkronisering är ETag mer kritiskt eftersom det möjliggör detektering av redigeringskonflikter. Om klienten skickar en PUT-förfrågan med If-Match: "etag"-huvudet avvisar servern förfrågan om resursen har ändrats av en annan klient (optimistisk låsning). Last-Modified kan inte garantera sådan tillförlitlighet på grund av sekundprecision.
Låt oss titta på klientimplementationen av ETag i en mobilapp i Kotlin med Retrofit och OkHttp. Vid varje GET-förfrågan sparar klienten ETag från svaret och vid nästa förfrågan skickar den den i If-None-Match-huvudet. Om servern returnerar 304 laddas inte data ner igen.
Konfiguration av OkHttp-klient med ETag-cachning:
class EtagClient {
private val etagCache =
mutableMapOf<String, String>()
private val client = OkHttpClient.Builder().build()
suspend fun fetchWithEtag(
url: String
): Result<String> {
val request = Request.Builder()
.url(url)
.header("If-None-Match",
etagCache[url] ?: "")
.build()
val response = client.newCall(request).await()
return when (response.code) {
304 -> Result.success(
"not_modified")
200 -> {
response.header("ETag")?.let {
etagCache[url] = it
}
Result.success(response.body?.string()
?: "")
}
else -> Result.failure(
Exception("HTTP ${response.code}"))
}
}
}
Klienten sparar ETag efter ett lyckat 200-svar och skickar den i If-None-Match-huvudet vid nästa förfrågan. Vid 304 vet klienten att den lokala versionen är aktuell och slösar inte trafik på att ladda ner data igen. Detta mönster minskar nätverkskostnaderna för mobilappen med 80–90% för ofta efterfrågade resurser.
ETag är en nyckelmekanism för att optimera synkronisering av mobilappar med REST API. I det standardsynkroniseringsschemat begär klienten först listan över resurser med ETag-validering — om ingen resurs har ändrats returnerar servern 304 och klienten avslutar synkroniseringen. Om det finns ändringar returnerar servern bara de ändrade resurserna. Denna metod kallas deltasynkronisering och är kritisk för mobila enheter med begränsad trafik.
I scenarier med optimistisk låsning används ETag för att förhindra Lost Update-konflikter. När klienten skickar en PUT-förfrågan för att uppdatera en resurs inkluderar den If-Match: "etag"-huvudet. Om ETag inte matchar (en annan klient har redan ändrat resursen) svarar servern med 412 Precondition Failed, och klienten måste ladda ner den aktuella versionen igen och upprepa ändringen. Denna metod säkerställer datakonsistens utan låsningar på databasnivå.
För distribuerade system med offlineläge används ETag i kombination med konfliktlösning. Klienten synkroniserar genom att hämta aktuella ETag för alla resurser. Vid sändning av ändringar kontrollerar servern If-Match — om ETag inte matchar registreras en konflikt som löses enligt den valda strategin (LWW, Merge). Enligt Postman API Report (2025) använder 67% av produktions-REST API:erna för mobilappar ETag som det primära versionsvalideringsmekanismen.
Vanliga frågor
ETag — HTTP-svarshuvud som innehåller en unik identifierare för resursversionen. Klienten använder den för villkorliga förfrågningar: om resursen inte har ändrats returnerar servern 304 Not Modified utan svarskropp, vilket sparar trafik.
ETag använder en innehållshash för exakt jämförelse. Last-Modified baseras på ändringsdatum med en sekunds precision. ETag är mer tillförlitligt för att upptäcka verkliga ändringar och stöder optimistisk låsning via If-Match.
Starka ETag (utan prefix) särskiljer resurser byte för byte. Svaga ETag (med prefix W/) tillåter semantisk ekvivalens. Starka krävs för intervallförfrågningar, svaga för dynamiskt genererat innehåll.
ETag minskar trafiken med 80–90%: klienten kontrollerar alla resursers aktuellitet via If-None-Match och laddar bara ner ändrade. Utan ETag skulle klienten ladda ner fullständiga data vid varje synkronisering, vilket slösar trafik och batteri.
Servern beräknar ETag som hash (MD5, SHA-256) av svarsinnehållet eller använder versionsnumret för posten i databasen. I Spring Boot räcker annoteringen @Cacheable med etag = true. I Express.js är etag-middlewaren aktiverad som standard.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också