Подробнее о заголовке Last-Modified можно почитать тут. Пожалуй, для SEO добавлю описание:
HTTP заголовок Last-Modified
сообщает клиенту (браузеру, поисковому боту) время последнего изменения страницы (объекта). Если клиент получил заголовок Last-Modified
, то при следующем обращении к адресу, при условии, что страница (объект) есть в локальном кэше, он добавит заголовок-вопрос If-Modified-Since
(не изменилась ли страница после даты, полученной в Last-Modified
).
В свою очередь сервер, получив запрос If-Modified-Since
должен сверить полученную временную метку с временем последнего изменения страницы и, если страница не изменялась ответить 304 Not Modified
.
Как добавить HTTP заголовок Last-Modified
на PHP в WordPress?
В целом на официальном сайте уже существует реализация на PHP, которую остаётся немного адаптировать для WP.
Отправка Last-Modified и обработка HTTP_IF_MODIFIED_SINCE на PHP
// время последнего изменения страницы в формате unix time
$lastModified = strtotime('2022-06-18 19:01:58');
// дата последней загрузки, отправляемая клиентом
$ifModified = strtotime(substr($_SERVER['HTTP_IF_MODIFIED_SINCE'] ?? '', 5));
if ($ifModified && $ifModified >= $lastModified) {
// страница не изменилась, отдача http статуса 304
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
exit;
}
header('Last-Modified: ' . gmdate("D, d M Y H:i:s \G\M\T", $lastModified));
// дальнейшая загрузка страницы
Получаем время последнего изменения страницы, проверяем наличие If-Modified-Since
, если есть — отдаем 304 Not Modified
и останавливаем работу скрипта, иначе генерируем заголовок Last-Modified
и отдаем страницу.
Версия для WordPress
Этот готовый код необходимо добавить в functions.php или через плагин. Я рекомендую добавлять этим методом.
/**
* Last-Modified and If-Modified-Since Headers
*/
add_action('wp', poet_'last_if_modified_headers' );
function poet_last_if_modified_headers() {
global $post;
if(isset($post)){
$LastModified_unix = strtotime($post->post_modified);
$LastModified = gmdate("D, d M Y H:i:s \G\M\T", $LastModified_unix);
$IfModifiedSince = false;
if (isset($_ENV['HTTP_IF_MODIFIED_SINCE'])) {
$IfModifiedSince = strtotime(substr($_ENV['HTTP_IF_MODIFIED_SINCE'], 5));
}
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$IfModifiedSince = strtotime(substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 5));
}
if ($IfModifiedSince && $IfModifiedSince >= $LastModified_unix) {
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
exit;
}
header('Last-Modified: '. $LastModified);
}
}
Настройки HTTP-сервера Nginx
Если вы используете в качестве веб-сервера Nginx , то есть вероятность столкнуться с проблемой отдачи заголовка. Всё дело в том, если у вашей конфигурации включена директива ssi
Модуль
https://nginx.org/ru/docs/http/ngx_http_ssi_module.htmlngx_http_ssi_module
— это фильтр, обрабатывающий команды SSI (Server Side Includes) в проходящих через него ответах.
Пример конфигурации при котором разрешается обработка команд SSI в ответах:
location / {
ssi on;
...
}
Следовательно, прицепом к этой директиве необходимо включить еще одну, которая по умолчанию выключена:
location / {
ssi on;
ssi_last_modified on;
}
Позволяет сохранить поле заголовка “Last-Modified” исходного ответа во время обработки SSI для лучшего кэширования ответов.
По умолчанию поле заголовка удаляется, так как содержимое ответа изменяется во время обработки и может содержать динамически созданные элементы или части, которые изменились независимо от исходного ответа.
Вот и всё 🙂
Обязательно перезапустите HTTP-сервер Nginx и протестируйте отдачу заголовка.
Внимание! Данный пример не гарантирует успешного запуска, так как конфигурации серверов зачастую требуют индивидуального подхода.
Вот правильная работа заголовка: