Настройка поведения HTTP-кэширования

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

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

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

  • server.js содержит код Node.js, который обслуживает содержимое веб-приложения. Он использует Express для обработки HTTP-запросов и ответов. В частности, 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-документу.

  • Нажмите Remix to Edit, чтобы сделать проект доступным для редактирования.

Статическая конфигурация обслуживания в 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');
    }
  },
}));

Подтвердите новое поведение с помощью DevTools.

После внесения изменений в статический файловый сервер вы можете проверить, установлены ли правильные заголовки, просмотрев активное приложение с открытой панелью DevTools Network.

  • Чтобы просмотреть сайт, нажмите «Просмотреть приложение» . Затем нажмите Полноэкранный режим полноэкранный .

  • Настройте столбцы, отображаемые на панели «Сеть», чтобы включить наиболее важную информацию, щелкнув правой кнопкой мыши заголовок столбца:

Настройка панели «Сеть» DevTools.

Здесь следует обратить внимание на столбцы 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 DevTools.