ETag: какво е, механизъм на кеширане и настройка на заглавието

Автор: IT Sectr Публикувано: 2026-03-09 Време за четене: 8 мин

ETag (Entity Tag) — HTTP заглавие, което присвоява уникален идентификатор на версията на ресурс на сървъра, позволявайки на клиента ефективно да проверява актуалността на кешираните данни. При повторно заявка браузърът или приложението изпраща запазения ETag, а сървърът го сравнява с текущия: при съвпадение се върща статус 304 Not Modified без тяло на отговора. Според RFC 7232 (IETF, 2014), условните заявки с ETag намаляват обема на предаваните данни до 95% за често заявявани ресурси. Това прави заглавието критично важно за производителността на мобилните приложения.

Основни позиции

  • ETag — HTTP заглавие с уникален идентификатор на версията на ресурса за условни заявки и кеширане
  • Принцип на действие — сървърът генерира хеш на съдържанието или номер на версията, клиентът го изпраща в заглавие If-None-Match
  • Силни и слаби ETag — силни (съдържанието е идентично байт по байт) и слаби (съдържанието е семантично еквивалентно, префикс W/)
  • 304 Not Modified — отговор на сървъра при съвпадение на ETag, икономи трафик и ускорява зареждането
  • ETag vs Last-Modified — ETag е по-точен (хеш на съдържанието), Last-Modified е по-прост (дата), заедно дават максимална ефективност

Какво е ETag?

ETag (Entity Tag) — е HTTP заглавие за отговор, което съдържа уникален идентификатор на определена версия на ресурс. Сървърът изчислява ETag на базата на съдържанието на файла, неговите метаданни или номера на ревизия и го предава на клиента в отговор на GET заявка. Клиентът запазва този идентификатор и при последващи заявки към същия ресурс го изпраща в заглавие If-None-Match. Ако ресурсът не е променен, сървърът отговаря 304 Not Modified, а клиентът използва кешираното копие.

Форматът на ETag е определен в RFC 7232 като низ в кавички: "33a64df551425fcc55e4d42a148795d9f25f89d4". Стойността може да бъде SHA-1 хеш на съдържанието на файла, инкрементален номер на версията, комбинация inode-номер-време за статични файлове или произволен токен, генериран от сървъра. Единственото изискване е стойността да се променя при всяка промяна на ресурса и да не се променя, ако ресурсът остане същият.

ETag принадлежи на механизмите за условни заявки (conditional requests) — една от основните оптимизации на HTTP протокола. За разлика от безусловните заявки, където сървърът винаги върща пълен отговор, условната заявка позволява на клиента да провери актуалността на кеша без да изтегля отново данните. Според данните на HTTP Archive (2025), около 40% от всички HTTP отговори са 304 Not Modified благодарение на правилната конфигурация на ETag и Last-Modified.

Къде се прилага ETag

ETag се използва в REST API за оптимизиране на зареждането на колекции от данни — ако списъкът на обектите не е променен, клиентът получава 304, без да изпраща цялия JSON. В статични файлове (CSS, JS, изображения) ETag позволява на CDN и браузърите ефективно да проверяват актуалността на кеша. В мобилните приложения ETag е критичен за фонова синхронизация: приложението проверява дали данните на сървъра са се променили и изтегля актуализации само при необходимост. Това икономи трафик и батерията на устройството.

Как работи ETag?

Пълният цикъл на работа на ETag се състои от четири стъпки. Сървърът генерира ETag при първата заявка и го върща в заглавието на отговора. Клиентът запазва ETag заедно с кеширания ресурс. При повторна заявка клиентът изпраща заглавие If-None-Match със стойността на запазения ETag. Сървърът сравнява получената стойност с текущия ETag на ресурса: при съвпадение върща 304 Not Modified с празно тяло, при несъвпадение — 200 OK с нов ресурс и нов ETag.

http
// Заявка на клиента с If-None-Match
GET /api/users HTTP/1.1
Host: example.com
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

// Отговор на сървъра — ресурсът не е променен
HTTP/1.1 304 Not Modified
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

В мобилно приложение този цикъл може да бъде реализиран чрез HTTP клиент с подкрепа на кеширане. OkHttp, например, автоматично управлява ETag чрез CacheInterceptor: запазва ETag на отговора и при повторна заявка добавя If-None-Match. След получаване на 304, OkHttp върща кешираните данни. OkHttp поддържа ETag без допълнителна конфигурация — достатъчно е да включите кеша чрез OkHttpClient.Builder.cache().

Генериране на ETag на сървъра

Сървърът може да изчислява ETag по различни начини: чрез MD5 или SHA хеш на съдържанието, чрез номер на ревизия от базата данни (например, updated_at от MySQL), чрез комбинация inode + mtime + size за статични файлове (Nginx генерира ETag именно по този начин). За динамични API най-надежден е хешът на съдържанието: ако JSON отговорът промени дори едно поле, ETag ще се промени. Изчисляването на хеша при всяка заявка обаче натоварва процесора — за системи с високо натоварване е по-добре да се използва инкрементален номер на версията.

Силни и слаби ETag

RFC 7232 определя два типа ETag: силни (strong) и слаби (weak). Силен ETag означава, че две представяния на ресурса са идентични байт по байт — нито един бит не се различава. Слабият ETag (префикс W/) гарантира само семантична еквивалентност: съдържанието може да се различава на ниво сериализация (интервали, ред на JSON полета), но данните се считат еднакви за клиента. Слабите ETag се означават с префикс W/, например W/"1a2b3c".

Изборът на типа ETag зависи от изискванията за точност на сравнението. За статични файлове (CSS, JS, изображения) предпочитани са силните ETag — ако файлът е променен, клиентът трябва да получи новата версия. За динамични API, където един и същ JSON може да бъде сериализиран с различен ред на полетата или форматиране, слабите ETag предоставят повече гъвкавост: сървърът генерира ETag на базата на бизнес данни, а не на текстовото представяне.

Тип ETagФорматГаранцияПриложение
Strong (силен)"хеш"Идентичност байт по байтСтатични файлове, бинарни ресурси
Weak (слаб)W/"хеш"Семантична еквивалентностJSON API, динамични страници

Ограничение на слабите ETag: те не могат да се използват с заявки за обхващане (Range requests). Ако клиентът изисква част от файла, сървърът трябва да върне силен ETag, за да гарантира, че фрагментът съответства на пълния ресурс. Слабите ETag не предоставят такава гаранция. В другите сценарии слабите ETag са безопасни и се препоръчват за API.

ETag vs Last-Modified

ETag и Last-Modified са две HTTP заглавия за условни заявки, които често се използват заедно. Last-Modified посочва датата на последната промяна на ресурса и работи с заглавие If-Modified-Since. ETag предоставя уникален идентификатор на версията и работи с If-None-Match. Всяко има своите предимства и ограничения, а комбинацията предоставя максимална ефективност на кеширането.

Last-Modified е по-лесен за имплементиране — сървърът автоматично получава датата от файловата система или актуализира полето updated_at в базата данни. Датата обаче има точност до секунда, което е недостатъчно за ресурси, които се променят няколко пъти в секунда. Освен това, Last-Modified не различава различните състояния: ако файлът е презаписан с същата версия, датата се променя, но съдържанието не — клиентът презарежда идентични данни.

ETag е по-точен: променя се само при реална промяна на съдържанието. Ако сървърът възстанови предишната версия от резервно копие, ETag ще се промени. Ако файлът е презаписан с същите данни — ETag ще остане същият, и клиентът няма да презарежда. Съвместното използване се препоръчва от HTTP спецификацията: сървърът върща и двете заглавия, клиентът изпраща If-None-Match и If-Modified-Since едновременно. Ако поне едно заглавие посочва промяна — сървърът върща нов ресурс.

Приоритет на заглавията

Според спецификацията, ETag има приоритет пред Last-Modified. Ако сървърът е получил If-None-Match, трябва да проверява само ETag, игнорирайки If-Modified-Since. Това предотвратява race condition: ако ресурсът се промени между изпращането на Last-Modified от клиента и проверката на сървъра, ETag ще бъде по-пресен показател. На практика сървърите обикновено проверяват и двете заглавия, но при несъвпадащи резултати ETag печели.

Имплементация на ETag на сървъра

Настройката на ETag зависи от типа на сървъра. Nginx генерира ETag за статични файлове автоматично на базата на inode, mtime и размер. Apache използва механизма FileETag. За динамични приложения в Node.js, PHP, Python, Ruby, ETag трябва да се генерира програмно — чрез хеш на отговора, номер на версията на данните или комбинация от параметри на заявката.

go
func etagMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter,
        r *http.Request) {
        // Генериране на ETag на базата на данни
        etag := generateETag(r.URL.Path)
        w.Header().Set("ETag", etag)

        // Проверка на If-None-Match
        if r.Header.Get("If-None-Match") == etag {
            w.WriteHeader(http.StatusNotModified)
            return
        }
        next.ServeHTTP(w, r)
    })
}

Middleware в Go прехваща заявката, генерира ETag за заявения URL (например, изчислява хеш на данните от кеша или базата данни) и задава заглавието на отговора. Ако клиентът е изпратил If-None-Match и той съвпада с текущия ETag, сървърът незабавно върща 304 Not Modified, без да вика основния handler. В производствена среда се препоръчва добавяне на кеширане на изчислените ETag по URL и параметри за намаляване натоварването на сървъра.

Проблеми и капани

В многосървърна конфигурация (round-robin или anycast) ETag трябва да бъде еднакъв на всички назли за един и същ ресурс. Ако ETag се генерира на базата на inode на файла, а сайтът работи на няколко сървъра, стойностите ще се различават. Решението — използване на хеш на съдържанието или централизирано съхранение на версии (Redis, etcd). Вторият проблем — gzip компресия: Nginx променя ETag, когато компресията е включена, което може да причини прекалени 304. Необходимо е настройката на gzip_vary on за синхронизация на ETag с компресираното съдържание.

Често задавани въпроси

Може ли ETag да бъде еднакъв за различни ресурси?

Да, ако сървърът явно не е предотвратил това. ETag не трябва да бъде глобално уникален — той е уникален в рамките на конкретен URL. За статични файлове колизиите са малко вероятни при използване на SHA хеш, но за собствени генератори са възможни дубликати.

Трябва ли да се настрои ETag за всеки ресурс?

ETag е най-ефективен за ресурси, които се заявяват многократно и редко се променят: статика, API списъци, конфигурации. За уникални страници, които се зареждат един път (например, страницата за потвърждаване на поръчка), ETag не предоставя предимство.

Как ETag работи с CDN?

CDN взема предвид ETag в origin заявките за проверка на актуалността на кеша. Ако ETag на ресурса на origin се промени, CDN изтегля новата версия. Cloudflare и Fastly поддържат ETag като стандартен механизъм за анулиране на кеша на ниво origin.

Може ли ETag да бъде по-дълъг от 255 знака?

RFC 7232 не ограничава дължината на ETag, но сървърите и проксита могат да съкратят или игнорират прекалено дълги стойности. Препоръчва се използването на хеш с дължина 20–40 знака или комбинация от идентификатор на версия с контролна сума.

Какво да избера: ETag или Cache-Control?

Това не са взаимно изключващи се механизми. Cache-Control определя политиката на кеширане (колко дълго да се пази, на кого е разрешено), а ETag е механизъм за валидация на кеширания ресурс. Оптималната конфигурация включва и двете заглавия заедно.

Обобщение

  • ETag — HTTP заглавие с уникален идентификатор на версията на ресурса за условни заявки и ефективно кеширане
  • Принцип — клиентът изпраща If-None-Match с запазен ETag, сървърът отговаря 304 при съвпадение
  • Силни ETag — идентичност байт по байт за статични файлове, слаби — семантична еквивалентност за API
  • ETag е по-точен от Last-Modified — проследява съдържанието, а не датата, и се променя само при реални промени
  • Съвместното използване с Last-Modified предоставя максимална ефективност на кеширането
  • Сървърна страна — генериране чрез хеш на съдържанието, номер на версията на данните или комбинация от параметри
  • Препоръка — използвайте ETag за всички API крайни точки и статични ресурси в мобилните приложения

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също