Делаем 301 редирект разными способами

В посте опишу самые популярные способы редиректа, как серверные так и скриптовые. Показывать буду на примере постоянного 301 редиректа (301 Permament Redirect — постоянный редирект). 301-ый код статуса HTTP, возвращается при обращении к определенному ресурсу и означает, что запрашиваемый документ был перенесен на новый адрес, причём на постоянной основе. Получив 301 код статуса HTTP все клиенты (user agents) будут перенаправляться по новому адресу. Обычно при 301 редиректе поисковые роботы производят «склейку» адресов, начального и конечно, как будто это одна страница.

Редирект с 301-ым кодом статуса запроса HTTP это пожалуй наилучший способ сохранить или передать рейтинг сайта. Естественно переадресацию можно выполнять разными способами:
Нижний уровень это переадресация от самого веб сервера. Самый надёжный и быстрый способ.
Далее идёт серверная скриптовая прослойка. Т.е. редирект можно сделать при помощи серверного языка программирования отправив нужные HTTP заголовки.
Ну и самые не надёжные переадресации на верхнем уровне, т.е. в уже в самом HTML и JavaScript коде, который передаётся непосредственно клиенту.

В этом посте я расскажу про все эти способы. Описывать методы 301 редиректа буду в такой же последовательности, что и привёл их выше.

301 редирект в файле .htaccess

На сервере apache, переадресацию можно выполнить с помощью файла дополнительной локальной конфигурации .htaccess (hiper text access). При этом понадобятся включения модулей mod_alias (для поддержки директив Redirect, RedirectPermanent и RedirectMatch) и/или mod_rewrite (для использования директив реврайта).

Редирект с помощью директивы Redirect или RedirectPermanent модуля mod_alias

Redirect 301 /old-page.html http://new-domain.ru/new-page.html
или
Redirect permanent /old-page.html http://new-domain.ru/new-page.html

Способ явно не подходит для массового редиректа. Все адреса, которые необходимо перенаправить, нужно перечислять один за одним, каждый отдельно на новой строке в новой дерективе Redirect. Также можно использовать директиву RedirectPermanent, которая предназначена именно для 301 редиректа.

RedirectPermanent /old-url.html http://new-site.ru/new-url.html

В этом случае указывать код статуса не требуется, он уже жёстко вбит для директивы RedirectPermanent.

Редирект с помощью директивы RedirectMatch

Применение этой директивы позволяет использовать регулярные выражения в задании старых адресов. Т.е. этот редирект идентичен предыдущему, но ещё можно задавать регулярное выражение для старых URL адресов.

Например, при смене серверного языка программирования с PHP на ASP, можно старые адреса перенаправить следующим образом:

RedirectMatch /(.*)\.php$ /$1.aspx

Все заканчивающееся на .php перенаправлять на такие же адреса файлов только с расширением .aspx

Редирект с помощью директивы RewriteRule модуля mod_rewrite

Для использования директивы RewriteRule необходимо удостовериться, что в файле конфигурации сервера Apache httpd.conf подключен модуль mod_rewrite, а также влючена опция FollowSymLinks для текущего виртуального хоста. Вообще модуль mod_rewrite очень мощный и его использование дает много возможностей для перенаправления запросов на любые адреса.

Перенаправление домена с www на не-www

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)	[NC]
# Хотя более точно так RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^(.*)$ http://%1/$1	[R=301,L]

Это универсальный способ, который действует всегда и код не надо исправлять для каждого конкретного сайта, очень удобно. Директивой +FollowSymLinks заставляем позволяем серверу отдавать файлы, которые физически находятся за пределами wwwroot директории, но на которые есть ярлыки/ссылки (symbolic link). Далее включаем RewriteEngine. Описываем условие для следующего правила, в данном случае берём HTTP_HOST из запроса и смотрим есть ли у него вначале префикс www, если да то применяется следующего правило описанное в директиве RewriteRule, а именно, все запросы перенаправяются такой же домен но уже без префикса www, флаг R говорит, что нужно использвать 301 редирект, а L сетует на то, что это последнее правило для выполнения. В формировании нового URL для редиректа в директиве RewriteRule переменная подстановки %1 берёт доменное имя без www из строки RewriteCond, т.е. всё, что заключено в круглые скобки, туда имя хоста подставляется из внутренней переменной сервера Apache %{HTTP_HOST}, которая, в свою очередь берётся из запроса клиента, а переменная строковых GET параметров запроса $1 в диретиве RewriteRule берётся из той же строки, но первого аргумента, там где описано регулярное выражения параметров запроса, точнее в конечную переменную попадает всё заключённое в круглые скобки регулярного выражения первого аргумента.

Так же есть и альтернативный, более понятный, но не универсальный синтаксис перенаправления домена с www на домен без www.

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.domain\.loc$ [NC]
RewriteRule ^(.*)$ http://domain.loc/$1 [R=301,L]

или вот так:

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://domain.loc/$1 [R=301,L]

Кстати, я такой дурацкий синтаксис долгое время использовал на своих сайтах, когда не знал, что в директиве RewriteRule при помощи переменной %1 можно динамически получить имя хоста без www из предыдущей директивы RewriteCond. Из-за этого приходилось править файл .htaccess для каждого домена, очень муторное дело когда много сайтов, проще использовать вариант который я привёл первым в этом примере, там всё универсально.

Редирект запросов с не-www на домен с www префиксом

Теперь предположим обратную ситуацию, на надо перенправлять на домен с префиксом www. Исходя из выше приведённых примеров и описаний не трудно догадаться как это сделать.

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^domain\.loc$ [NC]
RewriteRule ^(.*)$ http://www.domain.loc/$1 [R=301,L]

или же альтернативный, универсальный вариант:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.(.*) [NC]
RewriteRule ^(.*)$ http://www.%1/$1	[R=301,L]

Если имя хоста начинается не с www то редиректим на запрошенный хост и добавляем префикс www с точкой вначало.

Редирект с помощью серверного скрипта (отправки HTTP заголовков)

Редирект можно осуществлять также с помощью серверных скриптов, отправляя клиенту необходимые заголовки перенаправления:

HTTP/1.1 301 Moved Permanently
Location: http://www.newdomain.loc/newdir/newpage.html

После получения подобных HTTP заголовков любой user agent должен проследовать по адресу указанному в директиве Location. Стандарт этого заголовка обязывает указывть только полные абсолютные адреса веб ресурсов, включая протокол, никакие относительные адреса не поддерживаются, они будут считатья за ошибку.

Собственно всё, что нам нужно сделать в коде скрпитов, это передать данные HTTP заголовки клиенту.

Отправка HTTP заголовков редиректа на языке PHP

Для отправки заголовков в языке программирования PHP в базовой библиотеке есть специальная функция с одноимённым названием header. В качестве единственного строчного параметра они принимает заголовок, который впоследствии отдаст клиенту. Каждый заголовок нужно укзать в отдельном вызове функции ибо она топравляет их только по одному. Важно вызывать эту функцию до ночала отправки каких либо данных клиенту т.к. HTTP заголовки всегда отправляются в самом начале ещё до тела страницы.

<?php
header(“HTTP/1.1 301 Moved Permanently”);
header(“Location: http://www.newdomain.loc/newdir/newpage.html”);
exit();
?>

Вот и весь 301 первый редирект реализованный на PHP!

Отправка HTTP заголовков редиректа на ASP

<%@ Language=VBScript %>
<%
Response.Status=“301 Moved Permanently”
Response.AddHeader “Location”, “http://www.newdomain.loc”
response.end
%>

Практически всё тоже самое.

Отправка HTTP заголовков редиректа на ASP.NET

Здесь синтаксис очень схож с обычным ASP.

<script runat=“server”>
private void Page_Load(object sender, System.EventArgs e) {
Response.Status = “301 Moved Permanently”;
Response.AddHeader(“Location”,“http://www.new-url.loc”);
}
</script>

Редиректы на других языках

ColdFusion редирект

<.cfheader statuscode=“301” statustext=“Moved permanently”>
<.cfheader name=“Location” value=“http://www.new-url.loc”>

JSP (Java) редирект

<%
response.setStatus(301);
response.setHeader( “Location”, “http://www.new-url.loc/” );
response.setHeader( “Connection”, “close” );
%>

CGI PERL

$q = new CGI;
print $q->redirect(“http://www.new-url.loc/”);

Ruby on Rails

def old_action
headers[“Status”] = “301 Moved Permanently”
redirect_to “http://www.new-url.loc/”
end

Осуществление редиректа в серевере nginx

В веб сервере nginx разумеентся свои правила отличные от apache, однако это не сколько не условжняет работу.

if ($host = ‘old-domain.loc’ ) {
rewrite ^(.*)$ http://new-domain.loc$1 permanent;
}

Естественно должен быть подключен модуль ngx_http_rewrite_module.

Осуществление редиректа базовыми средствами HTML

В HTML так же есть базовые методы отправки заголовков. Для этого в блоке head используются служебные meta теги. Это не совсем HTTP заголовки ведь передаются они в HTML коде страницы, но суть в том, что любой клиент распознав подобыне инструкции должен их выполнить как если бы это было передано в HTTP заголовках. Конкретно для перенаправления в языке HTML для тега meta есть атрибут http-equiv со специальным значением Refresh (обновить, освежить). Т.е. стандартный редирект на HTML можно сделать так:

<html><head>
<meta http-equiv='Refresh' content='0; URL=new-domain.loc'>
</head></html>

Атрибут content указывет на вермя через которое стоит обновить страницу (в секунадах, ноль значит мгновенно) и конечный URL для редиректа.

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

На этом с редиректами всё.

Поделиться!
Tags: , , , , , , , , , , ,

49.79MB | MySQL:55 | 0,310sec