Last-Modified — същност, механизъм и настройка на заглавието за дата на промяна

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

Last-Modified — HTTP заглавие за отговор, което посочва дата и час на последната промяна на ресурса на сървъра, позволявайки на клиента да изпълнява условни заявки чрез If-Modified-Since. Ако ресурсът не е променен от посочената дата, сървърът връща 304 Not Modified без предаване на тялото на отговора, което значително икономи трафик. Според RFC 7232 (IETF, 2014), условните заявки с Last-Modified намаляват времето за зареждане на страниците с 30–60% при повторни посещения. Заглавието се поддържа автоматично от повечето HTTP сървъри и прокси сървъри.

Основни поенти

  • Last-Modified — HTTP заглавие с дата на последната промяна на ресурса за условни заявки If-Modified-Since
  • 304 Not Modified — отговор на сървъра, ако ресурсът не е променен; клиентът използва кешираното копие
  • Точност до секунда — ограничение: промените в рамките на една секунда могат да останат незабележани
  • Съвместна работа с ETag — сървърът връща и двете заглавия, клиентът изпраща и двете условни заявки
  • Автоматично генериране — Nginx и Apache настрояват Last-Modified за статично съдържание от файловата система

Какво е Last-Modified?

Last-Modified — HTTP заглавие, което е част от групата на заглавията за условни заявки (conditional requests). Сървърът го добавя в отговора на GET или HEAD, посочвайки дата и час на последната промяна на изискания ресурс в HTTP-date формат: Last-Modified: Wed, 02 Jul 2025 14:30:00 GMT. Клиентът (браузър, мобилно приложение, прокси) запазва тази дата заедно с кеширания ресурс. При повторна заявка клиентът изпраща заглавие If-Modified-Since с същата дата, и сървърът го сравнява с текущото време на промяна на ресурса.

Протоколът за условни заявки с Last-Modified е дефиниран в RFC 7232 и се поддържа от всички съвременни HTTP сървъри. Форматът на датата е строго регулиран — само GMT (Greenwich Mean Time) без посочване на часова зона. Сървърът може да върне датата в три възможни формата: RFC 1123 (стандартен), RFC 850 (остарял) или ANSI C asctime. На практика, почти всички сървъри използват RFC 1123 формат с фиксирана дължина от 29 знака.

Last-Modified принадлежи на категорията на механизмите за валидиране на кеша: то не казва на клиента дали може да кешира отговора, а предоставя инструмент за проверка на актуалността на вече кеширания ресурс. Политиката за кеширане се задава отделно чрез заглавие Cache-Control. Според проучване на Akamai (2025), правилната конфигурация на Last-Modified заедно с Cache-Control намалява товара на origin сървърите до 70% за статично съдържание.

Кога се появи Last-Modified

Заглавието Last-Modified е дефинирано още в HTTP/1.0 (RFC 1945, 1996) и е било един от първите механизми за управление на кеша в мрежата. Преди появата на ETag в HTTP/1.1, това бе единственият начин за изпълняване на условни заявки. Въпреки възраста си, заглавието остава актуално благодарение на своята простота — сървърът няма нужда да изчислява хеш на съдържанието, достатъчно е да прочете времевия печат на файла от файловата система или полето updated_at от базата данни.

Как работи Last-Modified?

Пълният цикъл включва три етапа. При първата заявка сървърът връща ресурса с заглавие Last-Modified и HTTP статус 200 OK. Клиентът кешира отговора заедно с датата. При повторна заявка клиентът изпраща заглавие If-Modified-Since с запазената дата. Сървърът сравнява тази дата с текущото време на промяна на ресурса. Ако ресурсът не е променен — връща се 304 Not Modified с празно тяло. Ако е променен — 200 OK с нови данни и нов Last-Modified.

http
// Първо искане — сървърът връща ресурса с дата
HTTP/1.1 200 OK
Content-Type: application/json
Last-Modified: Wed, 02 Jul 2025 14:30:00 GMT

[{"id": 1, "name": "Alice"}]

// Повторно искане — клиентът изпраща запазената дата
GET /api/users HTTP/1.1
Host: example.com
If-Modified-Since: Wed, 02 Jul 2025 14:30:00 GMT

// Отговор — данните не са се променили
HTTP/1.1 304 Not Modified

За мобилните приложения Last-Modified е особено полезен при синхронизация на данни. Приложението запазва датата на последното успешно обновяване и го изпраща на сървъра в If-Modified-Since. Ако има повече данни или те са се променили — сървърът връща пълен комплект. Ако не — 304, и приложението използва локално копие. OkHttp и URLSession поддържат този механизъм автоматично чрез вградените системи за кеширане.

Как сървърът определя датата

За статични файлове Nginx и Apache взимат датата от атрибутите на файловата система — mtime (време на промяна). За динамично съдържание кодът на сървъра трябва да настрои експлицитно Last-Modified на базата на бизнес логиката: полето updated_at от базата данни, датата на последния commit в Git, времевия печат на изграждане на артефакта. Ако Last-Modified не е настроен експлицитно, сървърът може изобщо да не върне заглавието, и клиентът няма да може да изпълнява условни заявки по дата.

Last-Modified срещу ETag

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

КритерийLast-ModifiedETag
СъщностДата на последна промянаУникален идентификатор на версия
ТочностДо секундаДо бит (hash)
Сложност на имплементациятаНиска — автоматично от файловата системаСредна — изисква изчисляване на хеш
Кластърни сървъриПроблем: mtime може да се различава на възлитеСтабилен при еднакви данни на възлите
Поддържка на диапазониНе влияе на Range заявкиИзисква силен ETag за диапазони
ПрепоръкаЗа статично съдържание и прости APIЗа API, където точната проверка е важна

Основното предимство на Last-Modified е простотата. Сървърът няма нужда да изчислява хеш на съдържанието, което икономи CPU ресурси при всяка заявка. За проекти с високо натоварване, които доставят статични файлове или данни с ясни времеви печати, Last-Modified остава оптималният избор. ETag пък предоставя абсолютна точност — промяната на една буква в JSON отговора ще промени ETag, но може да не промени датата (ако файлът е презаписан с същата версия).

Съвместна употреба

Спецификацията препоръчва едновременно въръщане на и двете заглавия. Сървърът включва и Last-Modified, и ETag в отговора 200 OK. Клиентът изпраща и двете условни заглавия — If-Modified-Since и If-None-Match. Сървърът проверява първо ETag (има приоритет), след което Last-Modified. Ако поне един от тях сигнализира промяна — връща се пълен отговор. Това осигурява максимална гъвкавост: ETag осигурява точност, Last-Modified — резервна проверка за клиенти, които не поддържат ETag.

Настройка Last-Modified на сървъра

Настройката на Last-Modified зависи от типа на сървъра. За Nginx и Apache, Last-Modified за статични файлове се настроява автоматично на базата на mtime. За динамични приложения заглавието трябва да се настрои в кода на сървъра. Нека разгледаме конфигурацията на популярните платформи.

javascript
// Express.js — настройка Last-Modified
app.get("/api/users", async (req, res) => {
    const updatedAt = await getLastUpdate()
    const ifModifiedSince = req.get("If-Modified-Since")

    // Проверка If-Modified-Since
    if (ifModifiedSince && new Date(ifModifiedSince)
        >= updatedAt) {
        return res.status(304).end()
    }

    const users = await getUsers()
    res.set("Last-Modified", updatedAt.toUTCString())
    res.json(users)
})

В примера с Express.js, сървърът получава датата на последното обновяване на данните от базата данни, проверява If-Modified-Since от клиента и ако кешът е актуален, връща 304. Ако данните са се променили — настроява нов Last-Modified и връща пълен отговор. toUTCString() преобразува датата в изисквания HTTP формат. В производствена среда се отплаща да се добави кеширане на updatedAt в Redis, за да се избегне запитване на базата данни при всяко обръщане.

Nginx: настройка Last-Modified

Nginx автоматично настроява Last-Modified за статични файлове на базата на времето на последната промяна на файла. Деактивирането или промяната на поведението може да се осъществи чрез директивата etag (деактивиране на ETag) или чрез модула ngx_http_headers_module. За proxy заявки към backend, Last-Modified се предава без промяна от upstream отговора. Важно: ако backend не връща Last-Modified, Nginx няма да го добави автоматично за динамични отговори.

Ограничения и капани

Last-Modified има няколко известни ограничения. Основното е точност до секунда. Ако ресурсът се промени два пъти в рамките на една секунда, клиентът може да пропусне новата версия. На практика това е рядко сценарий, но за високочестотни обновления (котировки, чатове) се препоръчва ETag. Второто ограничение е проблемът с кластеризацията: на различни сървъри файлът може да има различен mtime поради копиране или развъртване, което прави Last-Modified неконсистентен.

Третото ограничение — обработката на If-Modified-Since с точност до секунда може да доведе до ненужни заявки при често питане на сървъра. Ако клиентът изпраща If-Modified-Since на всяки 500 ms, сървърът всякадър връща 200 OK, защото датата не е променена, но ресурсът всъщност вече е обновен. Решението е комбинация с ETag: ETag ще улови промяната в рамките на секундата, а Last-Modified ще остане като резерва.

Четвъртият проблем — Last-Modified не различава различни версии на един и същ ресурс с еднаква дата. Ако файлът е восстановен от резервно копие и mtime му съвпада с оригинала, клиентът няма да забележи, че съдържанието е се променило. ETag решава този проблем: hash на съдържанието гарантирано ще се промени при всяка промяна на данните, независимо от времевия печат. За критични данни винаги използвайте и двете заглавия.

  • Точност до секунда — не улавя промени в рамките на една секунда; използвайте ETag за чести обновления
  • Кластеризация — mtime може да се различава на различни сървъри; синхронизирайте чрез NTP или използвайте ETag
  • Race condition — ако ресурсът се промени след изпращане на If-Modified-Since, но преди проверката на сървъра
  • Неправилна интерпретация от прокси — някои proxy могат да променят Last-Modified при кеширане; HTTPS решава този проблем

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

Каква дата се използва в Last-Modified?

Само GMT (Greenwich Mean Time) в RFC 1123 формат: ден от седмицата, дата, месец, година, часове:минути:секунди. Пример: Wed, 02 Jul 2025 14:30:00 GMT. Часовата зона е винаги GMT, други формати не са позволени.

Може ли Last-Modified да бъде в бъдещето?

Технически да, но това нарушава RFC 7232. Ако сървърът върне дата в бъдещето, клиентите няма да обновят ресурса до настъпването на тази дата. Такава конфигурация се счита грешка — датата трябва да бъде в миналото или настоящето.

Работи ли Last-Modified с POST заявки?

Не, условните заявки If-Modified-Since работят само с GET и HEAD. POST заявките не се кешират и не използват валидация по дата. За проверка на актуалността на данните за POST използвайте ETag или персонализирани механизми.

Как Last-Modified взаимодейства с Cache-Control?

Cache-Control определя политиката за кеширане (максимално време за съхранение, кой може да кешира), а Last-Modified е механизъм за валидация на изтеклия кеш. След изтичане на max-age, клиентът изпраща If-Modified-Since за проверка на актуалността.

Какво да правим, ако Last-Modified не се променя при обновяване на данните?

Проверете дали сървърът наистина настроява заглавието от актуалния източник — база данни, файлова система или API. За динамични отговори се уверете, че изрично извиквате res.setHeader("„"Last-Modified“", ...) в кода на handler-а.

Заключение

  • Last-Modified — HTTP заглавие с дата на последната промяна на ресурса за 304 условни заявки
  • Простота на имплементацията — работи автоматично за статика (mtime на файла) и изисква минимален код за API
  • Точност до секунда — основно ограничение; за чести промени използвайте ETag
  • ETag по-точен, Last-Modified по-прост — оптимална комбинация: и двете заглавия заедно
  • HTTP формат на дата — само GMT, RFC 1123, фиксирана дължина 29 знака
  • Кластеризация — изисква синхронизация на времето (NTP) или използване на ETag като основен механизъм
  • Препоръка — винаги добавяйте Last-Modified за API и го включвайте за статично съдържание чрез Nginx/Apache

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

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

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

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