Обработка запросов на сервере

Термин Fresh в контексте серверного программирования на JavaScript чаще всего связан с проверкой актуальности данных и кэшированием HTTP-ответов. Fresh отвечает за определение того, можно ли использовать закэшированный ответ без повторного обращения к серверу, что критически важно для повышения производительности веб-приложений и снижения нагрузки на сервер.

В HTTP Fresh реализуется через заголовки Cache-Control, ETag, Last-Modified и проверку If-None-Match / If-Modified-Since. На практике это позволяет серверу отвечать с кодом 304 Not Modified, если данные не изменились, что значительно экономит трафик и ускоряет отклик.


Заголовки, влияющие на Fresh

1. Cache-Control Основной механизм управления кэшированием на стороне клиента и промежуточных прокси. Содержит директивы:

  • public — ресурс можно кэшировать любым кэшем, включая общедоступные.
  • private — кэширование только на стороне конкретного пользователя.
  • no-cache — требует проверки актуальности перед использованием закэшированного ресурса.
  • no-store — полностью запрещает кэширование.
  • max-age=<seconds> — максимальное время жизни ресурса в секундах.

Пример:

Cache-Control: public, max-age=3600

Такой заголовок указывает, что ресурс можно хранить в кэше до 1 часа, после чего проверка Fresh становится обязательной.


2. ETag ETag (Entity Tag) — уникальный идентификатор версии ресурса. Сервер генерирует ETag на основе содержимого файла или данных, а клиент при следующем запросе отправляет заголовок If-None-Match, чтобы сервер проверил актуальность:

ETag: "12345abcdef"
If-None-Match: "12345abcdef"

Если ресурс не изменился, сервер вернёт 304 Not Modified, что означает, что клиент может использовать локальную копию.


3. Last-Modified Позволяет серверу сообщить дату последнего изменения ресурса:

Last-Modified: Tue, 22 Dec 2025 12:00:00 GMT
If-Modified-Since: Tue, 22 Dec 2025 12:00:00 GMT

Если данные не обновлялись, сервер отправляет 304 Not Modified. Этот механизм менее точен, чем ETag, так как основан на времени, а не на содержимом.


Проверка Fresh в Node.js

В Node.js существуют встроенные и сторонние способы определения актуальности запроса.

1. Встроенная проверка через req и res

Node.js позволяет вручную реализовать проверку ETag или Last-Modified:

const http = require('http');
const fs = require('fs');

http.createServer((req, res) => {
  const file = 'data.json';
  fs.stat(file, (err, stats) => {
    if (err) {
      res.statusCode = 500;
      return res.end('Server Error');
    }

    const lastModified = stats.mtime.toUTCString();
    res.setHeader('Last-Modified', lastModified);

    if (req.headers['if-modified-since'] === lastModified) {
      res.statusCode = 304;
      return res.end();
    }

    fs.readFile(file, (err, data) => {
      if (err) {
        res.statusCode = 500;
        return res.end('Server Error');
      }

      res.setHeader('Content-Type', 'application/json');
      res.end(data);
    });
  });
}).listen(3000);

В этом примере сервер проверяет, изменялся ли файл с момента последнего запроса, и при отсутствии изменений возвращает 304 Not Modified.


2. Использование Express и middleware

Express упрощает работу с Fresh через встроенные методы res.set и res.status:

const express = require('express');
const fs = require('fs');
const app = express();

app.get('/data', (req, res) => {
  const file = 'data.json';
  fs.stat(file, (err, stats) => {
    const lastModified = stats.mtime.toUTCString();
    res.set('Last-Modified', lastModified);

    if (req.headers['if-modified-since'] === lastModified) {
      return res.status(304).end();
    }

    fs.readFile(file, (err, data) => {
      res.set('Content-Type', 'application/json');
      res.send(data);
    });
  });
});

app.listen(3000);

Использование Express повышает читаемость кода и позволяет легко подключать middleware для управления кэшированием.


Принципы работы Fresh в сложных приложениях

1. Динамические данные Для динамических ресурсов, таких как результаты запросов к базе данных, ETag может строиться на основе хэша содержимого. Это обеспечивает точную проверку актуальности данных.

2. Статические ресурсы Для файлов JavaScript, CSS, изображений лучше использовать заголовки Cache-Control и ETag совместно. Это позволяет клиенту кэшировать большие ресурсы и обновлять их только при изменении.

3. Промежуточные прокси и CDN CDN и прокси часто используют Fresh для уменьшения нагрузки на исходный сервер. Правильная настройка ETag и Cache-Control критически важна для того, чтобы закэшированные версии ресурса были корректными.


Практические рекомендации

  • Использовать ETag для точного контроля версии ресурса.
  • Для часто обновляемых данных лучше использовать no-cache, чтобы всегда проверять актуальность.
  • Статические файлы можно отдавать с длительным max-age и уникальным ETag, чтобы клиентам не приходилось скачивать их заново при каждом запросе.
  • При работе с API важно обрабатывать заголовки If-None-Match и If-Modified-Since, чтобы уменьшить трафик и ускорить отклик.

Fresh — это не просто механизм кэширования, а инструмент оптимизации сетевых взаимодействий, который напрямую влияет на производительность, стабильность и экономию ресурсов веб-приложений.