Как стать автором
Обновить

Заголовок Last-Modified, Symfony и ускорение поисковой индексации

Symfony
Многие разработчики при создании сайтов забывают про очень полезный заголовок Last-Modified, благодаря которому можно оптимизировать загрузку web-страниц и облегчить работу поисковым роботам. Далее я постараюсь восполнить этот досадный пробел.


Для чего нужен заголовок 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.
Теги:last-modifiedif-modified-since304 not modifiedsymfony
Хабы: Symfony
Всего голосов 29: ↑27 и ↓2 +25
Просмотры35.3K

Похожие публикации

Fullstack разработчик (Symfony / Vue.js)
от 130 000 до 200 000 ₽ПродуманМожно удаленно
Symfony-разработчик‌
от 80 000 до 150 000 ₽Like ЦентрМожно удаленно
PHP Symfony разработчик
от 100 000 до 150 000 ₽DAMIR.INМожно удаленно
Senior PHP Developer (Symfony)
от 3 000 $RELAYTO/Можно удаленно
PHP developer (Symfony)
от 180 000 ₽GigAntСанкт-ПетербургМожно удаленно

Лучшие публикации за сутки