2011-09-14 18:31:45

Правильные редиректы на mod_rewrite

Про работу В мемориз Apache mod_rewrite SEO

Попробую описать свой небольшой опыт накопленный за долгое время по созданию правильных редиректов средствами Apache. Все описанные методы применяются для поисковой оптимизации сайта, но могут быть полезны и для других целей. С точки зрения поисковика, редирект "permanent" или "301" делает страницу не значимой и прибавляет вес тому адресу, на который ссылается.

Первое правило: не нужно использовать директивы Redirect и RedirectMatch совместно с mod_rewrite, это поможет избежать многих мучений.

1. Дописывание WWW и наоборот

Задача: сократить дубли страниц в индексе и устранить размазывание веса по двум и более хостам.

RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 

Здесь мы проверяем, что хост не начинается с www и отправляем на www.host + дописываем остальную часть урл. Аналогично можно сделать и отрывание www в случае его присутствия, но правила усложнятся.

2. Внутренние редиректы


Может сложится такая ситуация (в большинстве случаев так оно и есть), что в адрес попадает document_root при использовании вполне обычных правил вида

RewriteRule ^abc/yyy.html def/zzz.html [R=301,L] 

в результате посетитель отправится на адрес http://host/DOCUMENT_ROOT/def/zzz.html для того чтобы этого избежать нужно использовать вот такое правило

RewriteRule ^abc/yyy.html http://%{HTTP_HOST}/def/zzz.html [R=301,L] 

Такого рода редиректы применяются при смене адресов страниц, для того чтобы не потерять их в поисковой выдаче и др.

3. Принудительное приведение к "/" на конце

Используется для сокращения количества дублей страниц в системах (CMS) которые выдают одинаковые страницы по адресам http://host/page/ и http://host/page.html. По аналогии с предыдущим пунктом, вот такие правила

RewriteRule ^(.+)\.html$ $1/ [R=301,L]
RewriteRule ^(.+[^/])$ $1/ [R=301,L]

вызовут не только попадание document_root в урл, но и при отправке формы на folder/page.html методом POST произойдет потеря данных из POST запроса, поскольку на целевом адресе будет происходить редирект на другой. Для исправления ситуации можно использовать вот такие правила

RewriteCond %{REQUEST_METHOD} ^GET$ [NC]
RewriteRule ^(.+)\.html$ http://%{HTTP_HOST}/$1/ [R=301,L]

RewriteCond %{REQUEST_METHOD} ^GET$ [NC]
RewriteRule ^(.+[^/])$ http://%{HTTP_HOST}/$1/ [R=301,L] 

В этом случае не будут редиректится запросы отправленные методом, отличным от GET, а поскольку поисковые роботы не отправляют формы при индексации сайта, то от этого ничего не потеряем.

Последнее: QUERY_STRING, HTTP и HTTPS

Если в случае редиректа нужно дописать query_string, то в RewriteRule можно использовать ключ QSA.

Везде выше в примерах используется http при редиректе, если используется SSL, то нет ничего сложного, просто заменить http на https, а вот если используется и то и другое, то тогда придется использовать RewriteCond

RewriteCond %{HTTPS} ^off$ [NC]
# правила для http

RewriteCond %{HTTPS} ^on$ [NC]
# правила для https 

В этом случае количество правил удваивается. В принципе удвоения можно избежать путем установки переменной окружения в начале блока правил и последующего использования ее в каждом правиле, но это уже отдельная тема :)