-
-
Save aktaumag/4e036bff9cd32a74dc267800091e2c65 to your computer and use it in GitHub Desktop.
Обеспечение корректной обработки If-Modified-Since имеет чрезвычайно важную роль, если мы боремся за органический трафик. |
CMS Bitrix
В файле /bitrix/modules/main/lib/httpresponse.php
находим функцию public function writeHeaders()
if($this->lastModified !== null)
{
// START wSEO.kz
// В основном это касается товаров.
// Если мы знаем дату последнего изменения, то всё равно Отдаём её на обновление каждый месяц
// Текущее время по гринвичу gmmktime(часы, минуты, секунды, месяц, день, год)
$wsnaw = gmmktime(gmdate("H"), gmdate("i"), gmdate("s"), gmdate("m"), gmdate("d"), gmdate("Y"));
$LastModified_unix = $this->lastModified->getTimestamp();
$wsdday = gmdate("d",$LastModified_unix);
if($wsdday > 28) $wsdday = 28; // дата для удобства, так как 28 день есть во всех месяцах
// Формируем 28-ое число текущего месяца
$wstemp = gmmktime(gmdate("H",$LastModified_unix), gmdate("i",$LastModified_unix), gmdate("s",$LastModified_unix), gmdate("m"), $wsdday, gmdate("Y"));
// Если сформированная дата меньше реальной, то конечно отображаем реальную как есть, а если больше, то используем её
if($wstemp > $LastModified_unix){
if($wstemp < $wsnaw){
// если сформированная дата уже наступила
$LastModified_unix = $wstemp;
}
else {
// если сформированная дата больше текущей, то получаем такую-же дету месяц назад
$wsdm = gmdate("m") - 1;
$wsdy = gmdate("Y");
if($wsdm == 0){
$wsdm = 12; // Если прошлый месяц получился 0, значит это был декабрь
--$wsdy; // значит ещё и год отнять надо
}
$wstemp = gmmktime(gmdate("H",$LastModified_unix), gmdate("i",$LastModified_unix), gmdate("s",$LastModified_unix), $wsdm, $wsdday, $wsdy);
if($wstemp > $LastModified_unix){
$LastModified_unix = $wstemp;
}
}
}
// Бывают ситуации, когда дата создания статьи указана больше, чем текущая. Это делается, когда статьи пишутся заранее... они пока не отображаются
// Поэтому на всякий случай делаю сравнение дат. Выводим заголовки только для опубликованных статей с датой меньше текущей
if($wsnaw >= $LastModified_unix){
$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');
die();
}
header('Last-Modified: '. $LastModified);
$this->flushHeader(array("Last-Modified", $LastModified));
}
// wSEO.kz Закрыл старый вывод заголовка
//$this->flushHeader(array("Last-Modified", gmdate("D, d M Y H:i:s", $this->lastModified->getTimestamp()) . " GMT"));
// END wSEO.kz
}
В файле header.php от нашего шаблона прописываем в самом начале
// use \Bitrix\Conversion\Internals\MobileDetect;
if(!CSite::InDir('/product/')){
// У продуктов настроены заголовки Last-Modified и If-Modified-Since
// Поэтому исключаем их из этого обработчика
$wstt = 'na';
// $detect = new MobileDetect;
// $wsua = $detect->getUserAgent();
// // Сами заголовки прописываем только для ботов
// if (preg_match('/bot|LastModBot|crawl|curl|dataprovider|search|get|spider|find|java|majesticsEO|google|yahoo|teoma|contaxe|yandex|libwww-perl|facebookexternalhit/i', $_SERVER['HTTP_USER_AGENT'])) {
// // is bot
//
// }
// Текущее время по гринвичу gmmktime(часы, минуты, секунды, месяц, день, год)
$wsnaw = gmmktime(gmdate("H"), gmdate("i"), gmdate("s"), gmdate("m"), gmdate("d"), gmdate("Y"));
if(CSite::InDir('/catalog/') || $APPLICATION->GetCurPage(false) == '/') {
$wstt = 'catalog or main';
// если это главная или каталог
// Формируем каждый час новую дату
$LastModified_unix = gmmktime(gmdate("H"), gmdate("d"), gmdate("d")+gmdate("m"), gmdate("m"), gmdate("d"), gmdate("Y"));
// Задаём время обновления
$wsuptimer = 3600;
}
else {
$wstt = 'not catalog and not main and not product';
// Формируем каждый день новую дату
// Имитируя ежедневное обновление
$LastModified_unix = gmmktime(gmdate("m"), gmdate("d"), gmdate("d")+gmdate("m"), gmdate("m"), gmdate("d"), gmdate("Y"));
// Задаём время обновления
$wsuptimer = 86400;
}
if($wsnaw < $LastModified_unix){
// если сформированная время больше текущей, то отнимаем нужное время и генерируем дату так, как она была бы сгенерирована в то время
$wstest = $LastModified_unix - $wsuptimer;
$LastModified_unix = gmmktime(gmdate("H",$wstest), gmdate("d",$wstest), gmdate("d",$wstest)+gmdate("m",$wstest), gmdate("m",$wstest), gmdate("d",$wstest), gmdate("Y",$wstest));
}
if($wsnaw >= $LastModified_unix){
$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');
die();
}
header('Last-Modified: '. $LastModified);
}
}
else {
$wstt = 'product';
}
Если это хостинг nic.ru (RU-CENTER), то техподдержка не помогает даже для статических файлов, но можно перевести сервер в ручной режим управления и самому настроить конфигурацию Nginx.
Инструкция — https://www.nic.ru/help/nastrojka-sajta-kodirovka-perenapravlenie-logi-i-dr_6760.html#p6
Ищем в файле код:
# Static files location
location ~* ^.+\.(jpg|jpeg|gif|swf|png|ico|mp3|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|avi|ppt|txt|tar|mid|midi|wav|bmp|rtf|wmv|mpeg|mpg|mp4|m4a|spx|ogx|ogv|oga|webm|weba|ogg|tbz|js|7z|woff|svg|iso)$ {
root /home/login/domen.com/docs;
access_log /var/log/domen.com.access_log combined;
error_page 404 = @fallback;
log_not_found off;
accel_htaccess_switch on;
}
Добавляем в список локации woff2
и прочие недостающие форматы
И добавляем туда if_modified_since before;
и заодно expires 365d;
для кеша в браузере.
Нужно чтоб получилось так:
# Static files location
location ~* ^.+\.(jpg|jpeg|gif|swf|png|avif|webp|ico|mp3|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|avi|ppt|txt|tar|mid|midi|wav|bmp|rtf|wmv|mpeg|mpg|mp4|m4a|spx|ogx|ogv|oga|webm|weba|ogg|tbz|js|7z|woff|woff2|ttf|svg|iso)$ {
root /home/login/domen.com/docs;
access_log /var/log/domen.com.access_log combined;
error_page 404 = @fallback;
log_not_found off;
accel_htaccess_switch on;
if_modified_since before;
expires 365d;
}
Пример пути к файлу настроек:
/etc/nginx/vhosts/sites-enabled/site.ru.site.conf
/home/login/etc/nginx/site.ru.conf
/home/login/etc/nginx/sites-enabled/site.ru.site.conf
После внесения изменений в конфигурационные файлы Nginx достаточно перезапустить только Nginx, а не весь сервер.
Команда:
systemctl restart nginx
Плагин для добавления заголовков к постам Wordpress: https://wordpress.org/plugins/last-modified-and-if-modified-since-headers/
Заметка
Чтобы в PHP получить заголовок запроса
в .htaccess прописываем правило
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}]
RewriteRule .* - [E=HTTP_IF_NONE_MATCH:%{HTTP:If-None-Match}]
</IfModule>
А потом уже в самом PHP получаем значения переданные в запросе и возвращаем либо сайт, либо 304 ответ
$_SERVER['HTTP_IF_MODIFIED_SINCE']
и $_SERVER['HTTP_IF_NONE_MATCH']
Примерный пример (чужой код)
function caching_headers ($file, $timestamp) {
$gmt_mtime = gmdate('r', $timestamp);
header('ETag: "'.md5($timestamp.$file).'"');
header('Last-Modified: '.$gmt_mtime);
header('Cache-Control: public');
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime || str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == md5($timestamp.$file)) {
header('HTTP/1.1 304 Not Modified');
exit();
}
}
}
caching_headers ($_SERVER['SCRIPT_FILENAME'], filemtime($_SERVER['SCRIPT_FILENAME']));
Письмо хостеру или сисадмину (переделанное).
Добрый день!
Домен: (указать домен)Проверяю логотип: (ссылка на логотип)
На этом ресурсе: https://last-modified.com/ru/if-modified-since.html
Получаем ошибку: (скриншот)Для исправления ситуации в конфигурации Nginx нужно прописать настройку: if_modified_since before; для всех статических файлов.
Должно получиться примерно так:
# Static files location location ~* ^.+\.(jpg|jpeg|gif|swf|png|avif|webp|ico|mp3|css|zip|tgz|gz|rar|bz2|doc|docx|xls|xlsx|exe|pdf|avi|ppt|txt|tar|mid|midi|wav|bmp|rtf|wmv|mpeg|mpg|mp4|m4a|spx|ogx|ogv|oga|webm|weba|ogg|tbz|js|7z|woff|woff2|ttf|svg|iso)$ { # ... тут могут быть ещё и другие настройки для статических файлов if_modified_since before; }
Можете ли вы это сделать?
Или можете подсказать где/как я могу самостоятельно прописать эту настройку?
DLE
Почти в самое начало
engine/modules/show.full.php
, но когда уже получили переменную$row
В самое начало
engine/modules/main.php