Как настроить кеширование HTTP

В этой практической работе показано, как изменить заголовки кеширования HTTP, возвращаемые веб-сервером на основе Node.js, на котором работает фреймворк Express. Вы также узнаете, как с помощью панели "Сеть" в инструментах разработчика Chrome убедиться, что кеширование выполняется правильно.

Ознакомьтесь с примером проекта

Вот основные файлы, с которыми вы будете работать в примере проекта:

  • server.js содержит код Node.js, который обслуживает контент веб-приложения. Для обработки HTTP-запросов и ответов используется Express. В частности, express.static() используется для показа всех локальных файлов в общедоступном каталоге, поэтому вам пригодится документация по serve-static.
  • public/index.html – HTML-код веб-приложения. Как и в большинстве HTML-файлов, в его URL нет информации об управлении версиями.
  • public/app.15261a07.js и public/style.391484cf.css – это объекты JavaScript и CSS веб-приложения. Каждый из этих файлов содержит хеш в URL, соответствующий его содержимому. index.html отвечает за отслеживание того, какой именно URL с версией нужно загрузить.

Настройте заголовки кеширования для HTML-кода.

При ответе на запросы URL, которые не содержат информацию об управлении версиями, добавляйте в ответные сообщения заголовок Cache-Control: no-cache. Кроме того, рекомендуется задать один из двух дополнительных заголовков ответа: Last-Modified или ETag. К этой категории относится index.html. Это можно разбить на два шага.

Во-первых, заголовки Last-Modified и ETag контролируются параметрами конфигурации etag и lastModified. Оба этих варианта по умолчанию имеют значение true для всех HTTP-ответов, поэтому в текущей настройке вам не нужно включать эту функцию, чтобы получить такое поведение. Но вы можете явно указать его в конфигурации.

Во-вторых, вам нужно иметь возможность добавлять заголовок Cache-Control: no-cache, но только в HTML-документы (в данном случае – index.html). Проще всего задать этот заголовок условно – написать собственный setHeaders function и в нем проверять, запрашивается ли HTML-документ.

Конфигурация статического обслуживания в server.js выглядит следующим образом:

app.use(express.static('public'));
  • Внесите описанные выше изменения. В результате у вас должно получиться примерно следующее:
app.use(express.static('public', {
  etag: true, // Just being explicit about the default.
  lastModified: true,  // Just being explicit about the default.
  setHeaders: (res, path) => {
    if (path.endsWith('.html')) {
      // All of the project's HTML files end in .html
      res.setHeader('Cache-Control', 'no-cache');
    }
  },
}));

Настройте заголовки кеширования для URL с версиями

При ответе на запросы URL, которые содержат цифровой отпечаток или информацию об управлении версиями и контент которых не должен меняться, добавляйте в ответы Cache-Control: max-age=31536000. К этой категории относятся app.15261a07.js и style.391484cf.css.

На основе setHeaders function, использованного на предыдущем шаге, можно добавить дополнительную логику, чтобы проверять, запрашивается ли URL с версией, и если да, добавлять заголовок Cache-Control: max-age=31536000.

Самый надежный способ – использовать регулярное выражение, чтобы проверить, соответствует ли запрашиваемый объект определенному шаблону, в который попадают хеши. В нашем примере это всегда восемь символов из набора цифр от 0 до 9 и строчных букв от a до f (то есть шестнадцатеричные символы). Хеш всегда отделяется с обеих сторон символом ..

Регулярное выражение, которое соответствует этим общим правилам, можно записать как new RegExp('\\.[0-9a-f]{8}\\.').

  • Измените функцию setHeaders, чтобы она выглядела следующим образом:
app.use(express.static('public', {
  etag: true, // Just being explicit about the default.
  lastModified: true,  // Just being explicit about the default.
  setHeaders: (res, path) => {
    const hashRegExp = new RegExp('\\.[0-9a-f]{8}\\.');

    if (path.endsWith('.html')) {
      // All of the project's HTML files end in .html
      res.setHeader('Cache-Control', 'no-cache');
    } else if (hashRegExp.test(path)) {
      // If the RegExp matched, then we have a versioned URL.
      res.setHeader('Cache-Control', 'max-age=31536000');
    }
  },
}));

Как проверить новое поведение с помощью Инструментов разработчика

После изменения сервера статических файлов вы можете проверить, правильно ли заданы заголовки. Для этого откройте панель "Сеть" в Инструментах разработчика и посмотрите, как работает приложение.

  • Чтобы настроить столбцы, которые показываются на панели "Сеть", нажмите правой кнопкой мыши на заголовок столбца.

Настройка панели "Сеть" в Инструментах разработчика.

Обратите внимание на столбцы Name, Status, Cache-Control, ETag и Last-Modified.

  • Откройте панель "Сеть" в Инструментах разработчика и обновите страницу.

После загрузки страницы на панели "Сеть" должны появиться записи, похожие на следующие:

Столбцы на панели "Сеть".

В первой строке указан HTML-документ, к которому вы перешли. Это правильно подается с Cache-Control: no-cache. Статус HTTP-ответа на этот запрос – 304. Это означает, что браузер не стал сразу использовать кешированный HTML-код, а отправил HTTP-запрос на веб-сервер, используя информацию Last-Modified и ETag, чтобы проверить, есть ли обновления для HTML-кода, который уже находится в кеше. HTTP-ответ 304 указывает на то, что HTML-код не обновлен.

Следующие две строки предназначены для версий объектов JavaScript и CSS. Они должны быть представлены с Cache-Control: max-age=31536000, а статус HTTP для каждого из них должен быть 200. Из-за используемой конфигурации фактический запрос к серверу Node.js не выполняется, и при нажатии на запись отображаются дополнительные сведения, в том числе о том, что ответ поступил "(из кеша диска)".

Статус ответа сети – 200.

Фактические значения в столбцах ETag и Last-Modified не имеют большого значения. Главное – убедиться, что они заданы.

Подведение итогов

Выполнив шаги этой практической работы, вы узнали, как настроить заголовки HTTP-ответов на веб-сервере на базе Node.js с помощью Express для оптимального использования HTTP-кеша. Вы также знаете, как проверить, что используется ожидаемое поведение кеширования, с помощью панели "Сеть" в инструментах разработчика Chrome.