В этой лабораторной работе показано, как изменить HTTP-заголовки кэширования, возвращаемые веб-сервером на базе Node.js, работающим под управлением фреймворка Express . Также будет показано, как убедиться в том, что ожидаемое поведение кэширования действительно применяется, с помощью панели «Сеть» в инструментах разработчика Chrome.
Ознакомьтесь с примером проекта
Вот ключевые файлы, с которыми вы будете работать в примере проекта:
-
server.js
содержит код Node.js, обслуживающий контент веб-приложения. Он использует Express для обработки HTTP-запросов и ответов. В частности,express.static()
используется для обслуживания всех локальных файлов в каталоге public, поэтому документация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');
}
},
}));
Подтвердите новое поведение с помощью DevTools
После внесения изменений в статический файловый сервер вы можете проверить, установлены ли правильные заголовки, просматривая работающее приложение с открытой панелью DevTools Network.
- Настройте столбцы, отображаемые на панели «Сеть», чтобы включить в них наиболее релевантную информацию, щелкнув правой кнопкой мыши заголовок столбца:
Здесь следует обратить внимание на столбцы Name
, Status
, Cache-Control
, ETag
и Last-Modified
.
- Открыв DevTools на панели «Сеть», обновите страницу.
После загрузки страницы вы должны увидеть записи на панели «Сеть», которые выглядят следующим образом:
Первая строка относится к 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 не отправляется, и при нажатии на запись вы увидите дополнительную информацию, в том числе, что ответ получен «(из дискового кэша)».
Фактические значения столбцов ETag и Last-Modified не имеют большого значения. Важно убедиться, что они устанавливаются.
Подводя итоги
Выполнив шаги, описанные в этой лабораторной работе, вы теперь знаете, как настроить заголовки HTTP-ответа на веб-сервере на базе Node.js с помощью Express для оптимального использования HTTP-кеша. Вы также знаете, как убедиться в использовании ожидаемого поведения кэширования через панель «Сеть» в инструментах разработчика Chrome.