В контексте веб-разработки заголовки запросов играют ключевую роль в
управлении взаимодействием клиента и сервера, особенно при работе с
кэшированием. Правильная настройка заголовков позволяет оптимизировать
производительность, уменьшить нагрузку на сервер и обеспечить
актуальность данных. В JavaScript заголовки можно настраивать через
встроенные механизмы fetch и XMLHttpRequest, а
также через сервис-воркеры и промежуточные библиотеки.
Cache-Control Это основной заголовок, управляющий поведением кэша. Он может содержать несколько директив:
no-cache – заставляет браузер проверять у сервера
актуальность ресурса перед использованием локальной копии.no-store – запрещает хранение ресурса в кэше
полностью.max-age=<seconds> – задает максимальное время
жизни ресурса в кэше. После истечения этого времени браузер обязан
запросить свежую версию.public и private – определяют доступность
кэширования: public разрешает кэширование всеми,
private только для конкретного пользователя.Пример использования в fetch:
fetch('/api/data', {
headers: {
'Cache-Control': 'no-cache'
}
})
.then(response => response.json())
.then(data => console.log(data));
ETag Заголовок ETag используется для
проверки того, изменился ли ресурс на сервере. Сервер присваивает
уникальный идентификатор каждому состоянию ресурса. При последующих
запросах клиент может отправить этот идентификатор в заголовке
If-None-Match. Если ресурс не изменился, сервер вернет
статус 304 Not Modified, экономя трафик.
Пример использования:
fetch('/api/data', {
headers: {
'If-None-Match': '"1234567890"'
}
})
.then(response => {
if (response.status === 304) {
console.log('Используем кэшированную версию');
} else {
return response.json();
}
})
.then(data => console.log(data));
Last-Modified / If-Modified-Since
Last-Modified указывает время последнего изменения ресурса
на сервере. Клиент может использовать заголовок
If-Modified-Since для запроса только новых данных. Сервер
возвращает 304 Not Modified, если ресурс не изменился.
Пример:
fetch('/api/data', {
headers: {
'If-Modified-Since': 'Wed, 21 Oct 2025 07:28:00 GMT'
}
})
.then(response => {
if (response.status === 304) {
console.log('Данные не изменились');
} else {
return response.json();
}
})
.then(data => console.log(data));
Service Workers Сервис-воркеры позволяют реализовать сложную стратегию кэширования. Они перехватывают сетевые запросы и могут отдавать кэшированные ресурсы, проверять их актуальность или обновлять кэш асинхронно.
Пример простого service worker:
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(cachedResponse => {
if (cachedResponse) {
return cachedResponse;
}
return fetch(event.request).then(networkResponse => {
return caches.open('dynamic-cache').then(cache => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
});
})
);
});
Stale-while-revalidate Стратегия, позволяющая сразу отдавать старую версию ресурса из кэша, параллельно запрашивая свежую у сервера. После получения обновленной версии кэш обновляется.
no-cache или max-age=0 с
ETag/Last-Modified.max-age=31536000) с уникальными именами файлов для
обновления.Vary и Pragma.fetch поддерживает объект Request,
где можно задавать отдельные политики кэширования через свойство
cache (default, no-store,
reload, no-cache, force-cache,
only-if-cached).Пример:
fetch('/api/data', { cache: 'reload' })
.then(response => response.json())
.then(data => console.log(data));
Грамотное использование заголовков запросов позволяет контролировать процесс кэширования на всех уровнях: от браузера до сервера и промежуточных прокси. Комбинация директив Cache-Control, ETag, Last-Modified и современных подходов вроде сервис-воркеров обеспечивает высокую производительность и актуальность данных в приложениях на JavaScript.