Многие разработчики при создании сайтов забывают про очень полезный заголовок Last-Modified, благодаря которому можно оптимизировать загрузку web-страниц и облегчить работу поисковым роботам. Далее я постараюсь восполнить этот досадный пробел.
Функцией заголовка как можно догадаться из названия служит информирование клиента о дате последней модификации web-документа. Исходя из спецификации rfc 2616, клиент может «спросить» у веб сервера не изменилась ли страница с определенного числа, послав серверу заголовок «If-Modified-Since». Если страница не изменилась сервер возвращает только заголовок «304 Not Modified», в противном случае – сервер возвращает заголовок «200 OK» и тело страницы. Как видно, выгода на лицо как для сервера, так и для клиента: браузер не будет грузить страницу снова и снова, а веб сервер будет отдавать меньше данных.
Пару лет назад среди SEO-шников водились споры по поводу того, какие сайты индексируются лучше? Динамические, написанные например на php, или статичные, без использования языков программирования. Зная о заголовке Last-Modified, можно ответить на этот вопрос. Все дело в том, что веб сервер сам обрабатывает заголовок «If-Modified-Since» если файл статичный. В случае динамической генерации страницы вся ответственность за ответ ложится на язык программирования и разработчика. А так как разработчик за частую не интересуется этим вопросом, то заголовки не отдаются вовсе.
Все просто, как написано в помощи Яндекса, «робот не сможет получить информацию о том, обновилась ли страница сайта с момента последнего индексирования. А так как число страниц, получаемых роботом с сайта за один заход, ограничено, изменившиеся страницы будут переиндексироваться реже».
Представьте. Есть сайт с 10 тысячами страниц. Сайт написан на php. Не отдается корректно заголок Last-Modified. Поисковой робот не может получить информацию о том, обновилась ли страница сайта с момента последнего индексирования. Что он делает? Индексирует все страницы!!! А не только те, которые изменились.
Конечно! На многих сайтах используют Sitemap. Но Sitemap это рекомендация, помощь поисковому оптимизатору. Заменой заголовка Last-Modified он быть не может!
Для того чтобы веб-сервер передавал php-backend'у заголовок If-Modified-Since необходимо ему от этом сообщить!
Для связки nginx + php так,
Для связки apache + php, так
Если php работает как модуль, то ничего настраивать не надо!
Простой php-код обработки запроса If-Modified-Since,
В symfony уже предусмотрен механизм обработки заголовка. Все что нужно разработчику, так это передать в объект sfWebResponse заголовок. В случае его указания фрейморк все сделает сам.
Так как на странице как правило располагается разный контент, то я написал метод, который выставляет самый поздний из переданных заголовков!
Его очень удобно использовать в случае, если на странице, например, располагается 3 последних видеролика, 3 последних статьи и там еще что-нибудь. Загружая каждую модель из базы данных, мы можем вызывать метод, и в итоге в ответе получив самую позднюю дату модификации.
Для интересующихся код обработки заголовка находится в классе sfCacheFilter.class.php.
В заключение хочу сказать, что использование заголовка Last-Modified не всегда оправдано. Например, если на сайте 5 тысяч страниц и на каждой находится один и тот же блок с часто меняющимся контентом, использовать заголовок будет бесполезно! В этом случае можно разве что отдавать разные заголовки для клиентов и поисковых роботов. Но как по мне обман роботов ни к чему хорошему не приводит. Ну или убрать этот блок ;).
Еще,
Проверить сайт на корректную обработку заголовка можно тут или так,
Для чего нужен заголовок Last-Modified?
Функцией заголовка как можно догадаться из названия служит информирование клиента о дате последней модификации web-документа. Исходя из спецификации rfc 2616, клиент может «спросить» у веб сервера не изменилась ли страница с определенного числа, послав серверу заголовок «If-Modified-Since». Если страница не изменилась сервер возвращает только заголовок «304 Not Modified», в противном случае – сервер возвращает заголовок «200 OK» и тело страницы. Как видно, выгода на лицо как для сервера, так и для клиента: браузер не будет грузить страницу снова и снова, а веб сервер будет отдавать меньше данных.
Какие сайты индексируются лучше? Динамические или статичные?
Пару лет назад среди SEO-шников водились споры по поводу того, какие сайты индексируются лучше? Динамические, написанные например на php, или статичные, без использования языков программирования. Зная о заголовке Last-Modified, можно ответить на этот вопрос. Все дело в том, что веб сервер сам обрабатывает заголовок «If-Modified-Since» если файл статичный. В случае динамической генерации страницы вся ответственность за ответ ложится на язык программирования и разработчика. А так как разработчик за частую не интересуется этим вопросом, то заголовки не отдаются вовсе.
Как заголовок Last-Modified ускоряет поисковую индексацию?
Все просто, как написано в помощи Яндекса, «робот не сможет получить информацию о том, обновилась ли страница сайта с момента последнего индексирования. А так как число страниц, получаемых роботом с сайта за один заход, ограничено, изменившиеся страницы будут переиндексироваться реже».
Представьте. Есть сайт с 10 тысячами страниц. Сайт написан на php. Не отдается корректно заголок Last-Modified. Поисковой робот не может получить информацию о том, обновилась ли страница сайта с момента последнего индексирования. Что он делает? Индексирует все страницы!!! А не только те, которые изменились.
Конечно! На многих сайтах используют Sitemap. Но Sitemap это рекомендация, помощь поисковому оптимизатору. Заменой заголовка Last-Modified он быть не может!
Настройка и обработка заголовока Last-Modified в php
Для того чтобы веб-сервер передавал php-backend'у заголовок If-Modified-Since необходимо ему от этом сообщить!
Для связки nginx + php так,
location ~ \.php$
{
…
if_modified_since off;
fastcgi_pass fcgi;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /<путь > /web$fastcgi_script_name;
…
fastcgi_pass_header Last-Modified;
include fastcgi_params;
}
* This source code was highlighted with Source Code Highlighter.
Для связки apache + php, так
# If-Modified-Since (if php is not installed as cgi then comment lines below)
RewriteRule .* - [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}]
RewriteRule .* - [E=HTTP_IF_NONE_MATCH:%{HTTP:If-None-Match}]
* This source code was highlighted with Source Code Highlighter.
Если php работает как модуль, то ничего настраивать не надо!
Простой php-код обработки запроса If-Modified-Since,
$qtime = isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])? $_SERVER['HTTP_IF_MODIFIED_SINCE']:'' ;
$modified = substr(gmdate('r', $timestamp), 0, -5).'GMT';
if ($hdr == $modified)
{
header ("HTTP/1.1 304 Not Modified ");
header ("Last-Modified: $modified");
exit();
}
header ("Last-Modified: $modified");
//render
* This source code was highlighted with Source Code Highlighter.
Как обрабатывать запрос If-Modified-Since в symfony?
В symfony уже предусмотрен механизм обработки заголовка. Все что нужно разработчику, так это передать в объект sfWebResponse заголовок. В случае его указания фрейморк все сделает сам.
$datestamp = time();
$response->setHttpHeader('Last-Modified', $response->getDate($datestamp));
* This source code was highlighted with Source Code Highlighter.
Так как на странице как правило располагается разный контент, то я написал метод, который выставляет самый поздний из переданных заголовков!
static public function setLastModified($datestamp)
{
$response = sfContext::getInstance()->getResponse();
$request = sfContext::getInstance()->getRequest();
if(is_array($datestamp))
{
rsort($datestamp, SORT_NUMERIC);
$datestamp = $datestamp[0];
}
if(!$response->hasHttpHeader('Last-Modified'))
{
$response->setHttpHeader('Last-Modified', $response->getDate($datestamp));
}
else
{
$origLastModified = strtotime($response->getHttpHeader('Last-Modified'));
if($origLastModified < $datestamp)
$response->setHttpHeader('Last-Modified', $response->getDate($datestamp));
}
}
* This source code was highlighted with Source Code Highlighter.
Его очень удобно использовать в случае, если на странице, например, располагается 3 последних видеролика, 3 последних статьи и там еще что-нибудь. Загружая каждую модель из базы данных, мы можем вызывать метод, и в итоге в ответе получив самую позднюю дату модификации.
Для интересующихся код обработки заголовка находится в классе sfCacheFilter.class.php.
В заключение хочу сказать, что использование заголовка Last-Modified не всегда оправдано. Например, если на сайте 5 тысяч страниц и на каждой находится один и тот же блок с часто меняющимся контентом, использовать заголовок будет бесполезно! В этом случае можно разве что отдавать разные заголовки для клиентов и поисковых роботов. Но как по мне обман роботов ни к чему хорошему не приводит. Ну или убрать этот блок ;).
Еще,
Проверить сайт на корректную обработку заголовка можно тут или так,
<?php
$ch = curl_init();
$url = 'http://site.ru/1.php ';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'If-Modified-Since: Sun, 28 Nov 2010 15:45:53 GMT'
));
ob_start();
curl_exec ($ch);
curl_close ($ch);
$data = ob_get_contents();
ob_end_clean();
echo nl2br($data);
?>
* This source code was highlighted with Source Code Highlighter.