301 редирект используется в первую очередь, когда страница или группа страниц сменила свой адрес. Такое происходит в тех случаях, когда изменяется структура сайта, при смене образующей URL-страницы и т.д. Об этом многие владельцы сайтов не задумываются и поэтому возникают дубли страниц, что может привести к потере позиций либо наложению .

Помимо этого редирект 301 применяют для склейки зеркал (например, домен с www и без www). Это может способствовать повышению параметров тИЦ и PR, так как для поисковиков адрес сайта с "www" и без "www" - разные URL. Если владелец решил изменить адрес проекта в связи с изменением товаров и услуг, предоставляемых ранее, или решил зарегистрировать более короткий и красивый домен,- то здесь очень важно, чтобы посетители при обращении к адресу старого домена попадали на ту же страницу, что и ранее, но только уже расположенную на новом домене.

Redirect 301 в.htaccess

301 редирект в htaccess - это самый простой и популярный способ установки редиректов. Из преимуществ этого метода можно отметить тот факт, что он срабатывает на сервере до запуска различных скриптов ресурса и не создает дополнительную нагрузку. Вот несколько самых распространенных примеров (замените "сайт" на адрес вашего сайта):

301 редирект в.htaccess для домена с www. на домен без www.

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.raskruty\.ru$
RewriteRule ^(.*)$ http://сайт/$1

Обратный редирект с домена без www. на домен с www.

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^raskruty\.ru$
RewriteRule ^(.*)$ http://www.сайт/$1

Редирект 301 адреса c /index.php на корень сайта /

RewriteCond %{THE_REQUEST} ^{3,9}\ /index\.php\ HTTP/
RewriteRule ^index\.php$ http://www.сайт/

Еще один пример:

RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /index\.php
RewriteRule .* /

Тоже самое можно проделать и для /index.html, просто замените в примере php на html.

Редирект в nginx:

301 редирект в nginx для домена с www. на домен без www.

Server {
server_name www.сайт;
rewrite ^ http://сайт$request_uri? permanent;
}
server {
server_name сайт;
.... основной конфиг....
}

Еще пример (нежелательный):

If ($host = "www.сайт") {
rewrite ^/(.*)$ http://сайт/$1 permanent;
}

Редирект PHP:

header(“HTTP/1.1 301 Moved Permanently”);
header(“Location: http://www..html”);
exit();
?>

Редирект 301 часто используют как ответ сервера, заменяя этим действием традиционную ошибку 404 – Not Found. Если говорить проще, то посетитель при переходе по неправильной ссылке, либо на удаленную страницу, столкнется не с сообщением типа: «Извините, но такая страница удалена», а будет перенаправлен на другую действующую страницу. Хотя такой момент является спорным среди специалистов и поэтому тут присутствует несколько вариантов решений.

Во-первых, существует две категории ошибок 404: первая – традиционная (классическая), когда страница действительно отсутствует, а вторая – когда такая ошибка возникает из-за «кривых» внешних ссылок. Поэтому в первом случает лучше оставить все как есть, т. е. «ошибку 404». Но во втором случае лучше позаботиться о редиректе на правильный URL-адрес, если присутствует возможность восстановить его из битой ссылки либо перенаправить пользователя на главную страницу.

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

По возможности, нужно стремиться не допускать редиректов внутри ресурса. К примеру, если ссылки, ведущие с других ресурсов на сайт, исправить не удается и тут редирект обязателен, то битые внутренние ссылки необходимо исправлять. Хотя это может и не отразиться на ранжировании или индексации, но лучше подстраховаться и избежать таких спорных вопросов.

При составлении в.htaccess правил редиректов нужно исключать реальные адреса файлов и директорий на сервере и следить за выборкой.

, | |

HTTP-перенаправление (или редирект) – это способ направить один домен или адрес на другой. Существует несколько видов перенаправления, каждый из которых по-разному воспринимается клиентским браузером. Самые распространённые виды – это временный и постоянный редирект.

Временный редирект (302 Found) используется в случае если контент, доступный по одному URL-адресу, нужно временно обслуживать из другого каталога. К примеру, если сайт находится на обслуживании, вы можете перенаправить запросы к домену на пользовательскую страницу ошибок, где посетители смогут узнать, когда сайт будет доступен.

Постоянный редирект (301 Moved Permanently) сообщает браузеру о том, что старый адрес больше не доступен, а контент обслуживается по другой ссылке. Такой редирект полезен при смене доменного имени.

Чтобы создать временный редирект в Nginx, добавьте в виртуальный хост (блок server) такую строку:

rewrite ^/oldlocation$ http://www.newdomain.com/newlocation redirect;

Чтобы создать постоянный редирект, нужно ввести:

rewrite ^/oldlocation$ http://www.newdomain.com/newlocation permanent;

В руководстве вы найдёте более подробное описание настройки каждого вида перенаправления в Nginx и несколько полезных примеров.

Требования

  • Настроенный сервер.
  • Установленный веб-сервер Nginx.
  • Виртуальный хост (эти руководства помогут создать виртуальный хост в , и ).

Простая настройка редиректа

Чтобы настроить простой редирект одной страницы в Nginx, можно использовать директиву rewrite, которая доступна по умолчанию. Директиве нужно иметь минимум два аргумента: старый URL-адрес и новый URL-адрес. С её помощью можно настроить как временное, так и постоянное перенаправление.

Чтобы настроить простое временное перенаправление, добавьте следующие строки в конфигурации сервера:

server {
. . .
server_name www.domain1.com;
rewrite ^/$ http://www.domain2.com redirect;
. . .
}

Теперь браузер будет направлять все запросы к www.domain1.com на домен www.domain2.com. Однако такое решение работает только с одностраничными сайтами.

Редирект объемных сайтов настраивается с помощью директивы rewrite и регулярных выражений, что позволяет указать целый каталог вместо одного файла.

Директива redirect выполняет поиск по шаблонам регулярных выражений в круглых скобках, а затем ссылается на найденный текст как на целевой каталог переадресации с помощью выражения $1 (где 1 — первая группа найденного текста). В более сложных примерах перенаправления группы, совпавшие с шаблонами, получают последовательные номера.

К примеру, чтобы временно перенаправить все страницы домена www.domain1.com на www.domain2.com, нужно добавить в файл:

server {
. . .
server_name www.domain1.com;
rewrite ^/(.*)$ http://www.domain2.com/$1 redirect;
. . .
}
server {
. . .
server_name www.domain2.com;
. . .
}

По умолчанию директива rewrite устанавливает временный редирект. Чтобы с её помощью настроить постоянный редирект, нужно заменить опцию redirect опцией permanent:

rewrite ^/$ http://www.domain2.com permanent;
rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;

Теперь рассмотрим пару примеров.

Пример 1: переход на другой домен

Предположим, у вас есть сайт, который пользуется популярностью, но в какой-то момент у вас возникла необходимость сменить его домен. Конечно, вы не можете просто переместить контент на новый домен, а старый забросить: так вы потеряете своих посетителей. Кроме того, ссылки на ваш сайт, расположенные на других сайтах, перестанут работать, если вы просто перенесёте контент на новый домен и не оставите никакой информации о его новом местонахождении. Все это приведёт к снижению трафика. Как переместить контент сайта на новый домен и не потерять аудиторию?

В таком случае нужно настроить редирект со старого домена (например, domain1.com) на новый (domain2.com). Чтобы навсегда сменить доменное имя сайта, используйте постоянный редирект. Благодаря этому браузер сможет перенаправлять поступающий трафик на новый домен.

Итак, предположим, что на данный момент сайт обслуживается по домену domain1.com, а его настройки в Nginx выглядят так:

server {
. . .
server_name domain1.com;
. . .
}

Также предполагается, что веб-сервер обслуживает новый домен, domain2.com:

server {
. . .
server_name domain2.com;
. . .
}

Теперь измените настройки виртуального хоста domain1.com (/etc/nginx/sites-available/domain1.com) и добавьте в них постоянный редирект на domain2.com:

server {
. . .
server_name domain1.com;
rewrite ^/(.*)$ http://domain2.com/$1 permanent;
. . .
}

В данном случае используется директива rewrite и регулярное выражение ^/(.*)$. Выражение совпадает с любым текстом, идущим в URL-адресе после /. Таким образом, http://domain1.com/index.html будет перенаправляться на http://domain2.com/index.html.

Чтобы настроить постоянный редирект, нужно просто добавить опцию permanent.

Примечание : После изменения виртуального хоста нужно перезапустить Nginx, чтобы обновить настройки:

systemctl restart nginx

Пример 2: перенаправление страницы

В некоторых ситуациях возникает необходимость изменить название уже опубликованной страницы. Если вы просто измените название (без настройки редиректа), при запросе исходного URL-адреса страницы будет возникать ошибка 404 Not Found. Тогда пользователь, который добавил эту страницу в закладки, не сможет найти её, поскольку он использует устаревшую ссылку. Редирект позволяет устранить эту проблему.

Предположим, на вашем сайте есть две отдельные страницы для товаров и услуг, products.html и services.html соответственно, и вы решили объединить эти страницы в одну, offers.html. Чтобы не потерять трафик, нужно настроить редирект products.html и services.html на offers.html.

К примеру, настройки сайта выглядят так:

server {
. . .

. . .
}

Чтобы настроить редирект двух страниц, используйте две директивы rewrite.

server {
. . .
server_name example.com www.example.com;
rewrite ^/products.html$ /offer.html permanent;
rewrite ^/services.html$ /offer.html permanent;
. . .
}

Директива rewrite принимает исходный адрес страницы, которую нужно перенаправить, а затем адрес новой страницы. Опция permanent обеспечит постоянный редирект. Вы можете использовать неограниченное количество директив rewrite в виртуальном хосте, чтобы перенаправить трафик на новые страницы сайта.

Заключение

Теперь вы умеете перенаправлять запросы пользователей. При настройке перенаправления будьте внимательны: неправильное использование временных редиректов может повредить ваш поисковый рейтинг.

Редирект HTTP применяется также для обеспечения SSL-шифрования трафика (редирект http на https) и добавления префикса www к домену сайта.

После переноса одного сайта на CSM Битрикс работающего на хостинге с apache на другой хостинг с вебсервером nginx , все правила в .htaccess стали непригодны. Благо их было не много. Разобравшись как и где прописать подобные правила для nginx , стандартное правило для скрипта обработки адресов 1C Битрикс (urlrewrite.php) нашел достаточно быстро:



.htaccess
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-l RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !/bitrix/urlrewrite.php$ RewriteRule ^(.*)$ /bitrix/urlrewrite.php [L]
nginx.conf
f (!-e $request_filename) { rewrite ^(.*)$ /bitrix/urlrewrite.php last; }
На 2 других правила потратил времени чуть больше, т.к. найденные в сети примеры просто не работали или не подходили:
1. Редирект с поддомена www
2. Редирект с добавлением слэша "/" в конце строки при обращении к адресам без слеша.

.htaccess

#Remove "www" RewriteCond %{HTTPS} !=on RewriteCond %{HTTP_HOST} ^www\.(.+)$ RewriteRule ^ http://%1%{REQUEST_URI} #Add "/" RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_URI} (.*/[^/.]+)($|\?) RewriteRule .* %1/


По www хотелось получить универсальное правило как было в .htaccess , не привязанное к названию конкретного домена. В итоге получил такой результат:

nginx.conf
#Remove "www" #Хост соответствует регулярному выражению if ($http_host ~* "^www\.(.+)$"){ #Запоминаем хост без www из предыдущего выражения в переменной $nowww set $nowww $1; #Делаем 301 редирект (permanent) #В $request_uri - адрес без хоста со всеми GET параметрами #После $request_uri добавляем "?" чтобы GET параметры #не добавились дважды (по умолчанию) rewrite ^ http://$nowww$request_uri? permanent; } #Add "/" #Это не существующий файл/каталог... if (!-e $request_filename){ #301 редирект с добавлением "/" rewrite (.*/[^/.]+)($|\?) $1/ permanent; }

В моем случае я просто вставил правила в нужные существующие директивы файла nginx.conf . Правила для nginx должны быть указаны внутри директивы конфигурации server:

Server { .... if (!-e $request_filename){ rewrite (.*/[^/.]+)($|\?) $1/ permanent; } .... }
P.S . Полученного опыта недостаточно чтобы сравнивать apache и nginx. О плюсах и минусах можно найти материалы в сети, но один неудобный момент при использовании nginx.conf - нужно выполнять перезапуск сервиса nginx после каждого изменения конфигурации.

Bonus : Встроенные переменные nginx которые можно использовать при конфигурировании:

$args, эта переменная равна аргументам в строке запроса; $arg_name, эта переменная равна аргументу name в строке запроса; $binary_remote_addr, эта переменная равна адресу клиента в бинарном виде, длина её значения всегда 4 байта; $content_length, эта переменная равна строке "Content-Length" в заголовке запроса; $content_type, эта переменная равна строке "Content-Type" в заголовке запроса; $cookie_name, эта переменная равна cookie name; $document_root, эта переменная равна значению директивы root для текущего запроса; $document_uri, то же самое, что и $uri; $host, эта переменная равна строке "Host" в заголовке запроса или имени сервера, на который пришёл запрос, если этой строки нет; $hostname, эта переменная равна имени хоста; $http_name, эта переменная равна строке name в заголовке запроса; $is_args, эта переменная равна "?", если в строке запроса есть аргументы, и пустой строке, если их нет; $limit_rate, эта переменная позволяет установить ограничение скорости соединения; $pid, эта переменная равна номеру рабочего процесса; $request_method, эта переменная равна методу запроса, обычно это "GET" или "POST"; $remote_addr, эта переменная равна адресу клиента; $remote_port, эта переменная равна порту клиента; $remote_user, эта переменная равна имени пользователя, используемого в Basic аутентификации; $realpath_root, эта переменная равна значению директивы root для текущего запроса, при этом все символические ссылки преобразованы в реальные путь; $request_filename, эта переменная равна пути к файлу для текущего запроса, формируемому из директив root или alias и URI запроса; $request_body, эта переменная содержит тело запроса. Значение переменной появляется в location"ах, обрабатываемых директивами proxy_pass и fastcgi_pass. $request_body_file, эта переменная равна имени временного файла, в котором хранится тело запроса. По завершению работы файл необходимо удалить. Для того, чтобы тело запроса клиента всегда записывалось в файл, нужно указать client_body_in_file_only on. При передаче имени в проксированном запросе или в запросе к FastCGI-серверу следует запретить передачу самого тела директивами "proxy_pass_request_body off" или "fastcgi_pass_request_body off" соответственно. $request_uri, эта переменная равна полному первоначальному URI вместе с аргументами; $query_string, то же самое, что и $args; $scheme, эта переменная равна схеме запроса — "http" или "https"; $server_protocol, эта переменная равна протоколу запроса, обычно это "HTTP/1.0" или "HTTP/1.1"; $server_addr, эта переменная равна адресу сервера, на который пришёл запрос. Как правило, для получения значения этой переменной делается один системный вызов. Для того, чтобы избежать системного вызова, нужно указывать адреса в директивах listen и использовать параметр bind; $server_name, эта переменная равна имени сервера, на который пришёл запрос; $server_port, эта переменная равна порту сервера, на который пришёл запрос; $uri, эта переменная равна текущему URI в запросе, он может отличаться от первоначального, например, при внутренних редиректах или при использовании индексных файлов.

Если у вас на сайте есть SSL сертификат для домена, то вы можете настроить https протокол. После чего для 301-го редиректа вам необходимо добавить следующий код в файл конфигурации nginx для домена:

Server { #... if ($scheme = http) { return 301 https://$server_name$request_uri; } }

Server { #... listen server_ip:80; server_name www.devreadwrite.com; rewrite ^ https://www.devreadwrite.com$request_uri? permanent; }

Nginx, 301 редирект с https на http протокол

Обратный пример конфигурации для редиректа с http на https:

Server { listen 443; server_name www.devreadwrite.com; rewrite ^ http://www.devreadwrite.com$request_uri? permanent; } server { listen 80; server_name www.devreadwrite.com; #... }

Nginx, 301 редирект с www на без www

Пример 301-го редиректа на основное зеркало без www:

Server { #... if ($host ~* www\.(.*)) { set $host_without_www $1; rewrite ^(.*)$ http://$host_without_www$1 permanent; } }

Server { #... server_name www.devreadwrite.com; rewrite ^/(.*)$ http://devreadwrite.com/$1 permanent; }

Nginx, 301 редирект с без www на с www

Обратный пример 301-го редиректа на основное зеркало сайта с www:

Server { #... server_name devreadwrite.com; rewrite ^/(.*)$ http://www.devreadvrite.com/$1 permanent; } server { listen 80; server_name www.devreadvrite.com; #... }

Nginx, 301 редирект для одной страницы

Если у страницы поменялся URL, то лучше сделать 301 редирект на новый URL:

Server { #... if ($request_filename ~ oldpage/) { rewrite ^ http://www.devreadvrite.com/newpage/? permanent; } #... }

Nginx, 301 редирект для папки

Аналогичный пример 301-го редиректа для папки:

Server { #... if ($request_filename ~ oldfolder/.+) { rewrite ^(.*) http://www.devreadvrite.com/newfolder/$1 permanent; } #... }

Nginx, 301 редирект с одного домена на другой

Если вы сменили домен сайт и хотите перенести вес старого домена на новый, то можно сделать 301-й редирект со старого домена на новый:

Server { server_name domain.com www.devreadvrite.com; rewrite ^ $scheme://www.new-devreadvrite.com; }

Nginx, 301 редирект с каждой страницы одного домена на такой же URL адрес другого домена

Если вы планируете изменить свой домен или изменить название предприятия, то перенаправление домена является единственным лучшим решением для сохранения пользователей и перевода их запросов на новый домен.

Server { server_name devreadvrite.com www.devreadvrite.com; rewrite ^ $scheme://www.new-devreadvrite.com$request_uri permanent; }

Nginx, 301 редирект со страниц со слешем на страницы без слеша в конце URL

Часто бывает так что одна и та же страница доступна по двум URL, например /may-best-page и /my-best-page/, если человеку понятно что это одна и та же страница, то поисковые системы понимают это как две разные страницы, соответственно разбивают вес страницы, а также показываются в аналитике (статистике) как 2 разные страницы. Для того, что бы избежать этого вы можете сделать 301 редирект со страниц со слешем в конце URL на без него:

Server { #... rewrite ^/(.*)/$ /$1 permanent; #... }

Nginx, 301 редирект со страниц без слеша на страницы со слешем в конце URL

Причина делать такой редирект та же, что и в ситуации описанным выше, за исключением того, что редирект необходимо делать со страницы без слеша в конце URL на страницу со слешем в конце URL:

Server { #... rewrite ^(.*[^/])$ $1/ permanent; #... }

Дополнительно

Не забудьте перед использованием примеров сменить devreadwrite.com на свой домен. После внесения изменений в файл конфигурации nginx для домена необходимо перезапустить nginx:

Service nginx reload

Nginx is an extremely efficient and quite flexible web server. When you want to do a redirect in Nginx, you have a few options to select from, so you can choose the one that suits you best to do an Nginx redirect.

Simplest and fastest: return

The by far simplest and fastest – because there is no regexp that has to be evaluated – is to use the return statement. Place this in your server block:

Return 301 https://example.com$request_uri;

This is a permanent redirect. Use 302 if you want a temporary redirect. A full sample server block could be:

Server { listen 80; listen [::]:80; hostname example.com www.example.com; return 301 https://example.com$request_uri; }

Using regular expressions

If you need something more complex, don’t be afraid to use a regexp – they’re still extremely fast in Nginx:

Rewrite ^/foo/(bar)/(.*)$ https://$server_name/$1/$2 permanent;

Replace permanent with redirect if you want a temporary (HTTP 302) redirect. Our full sample server block could then be:

Server { listen 80; listen [::]:80; hostname example.com www.example.com; root /var/www/example.com/public; rewrite ^/foo/(bar)/(.*)$ $scheme://$server_name/$1/$2 permanent; }

Using maps

If you have a list of URLs or regular expressions that you want to redirect differently, you ought to look into using a map, which you very well may define in a separate file for your convenience. Just note that the map definition must be outside the server block:

Include redirect-map.conf; server { […] if ($redirect_uri) { return 301 $redirect_uri; } }

The file redirect-map.conf may then look something like this:

Map $request_uri $redirect_uri { /about.html /about-us; /customers.html /our-customers; /products.html /our-products; }

Note the following excerpt from the docs:

A regular expression should either start from the “~” symbol for a case-sensitive matching, or from the “~*” symbols (1.0.4) for case-insensitive matching. A regular expression can contain named and positional captures that can later be used in other directives along with the resulting variable.

Here’s an example that might help you understand what that was about:

Map $request_uri $redirect_uri { /about.html /about-us; /customers.html /our-customers; /products.html /our-products; # Match any url that ends in products.html or producs.htm ~products\.html?$ /our-products; # case-insensitive version of the above ~*products\.html?$ /our-products; # A named capture that maps # e.g. product-1234.html into /products/item-1234/overview ~product-(?\d+)\.html /products/item-$sku/overview; }

Cute, huh? :-) Also please note that the variable name $redirect_uri have no special meaning: It is one I made up. You can name it whatever you like, but make sure the variable name in the map and the server block matches.

Some useful variables

I’ve used a few of these in the examples above, so you might have noticed them before. These are variables that comes predefined by Nginx, ready for you to use in your configs:
$scheme – The scheme used for the current request. E.g. “http” or “https”
$host – The hostname provided by the client for the current request.
$server_name – The first hostname from the hostname declaration in your config for the server block that responds to the request.
$request_uri – The full original request URI – with arguments.
$request_filename – The file path for the current request.

Some useful recipes for an Nginx redirect

HTTP to HTTPS

return 301 https://$host$request_uri;

Canonical hostname

If the hostname doesn’t match the first name in the server_name list. Makes sure your content is only available at the canonical hostname, e.g. to avoid duplicate content issues. Excellent for redirecting non-www to www or redirecting www to non-www in Nginx as long as your server block is only for a single website.

Server_name example.com www.example.com example.net www.example.net _; if ($host != $server_name) { return 301 $scheme://$server_name$request_uri; }

Nginx is very efficient, but please note that it would be more efficient to have two separate server blocks – one for the hostnames you want to redirect and one for the website. Then Nginx won’t have to do the comparison for every request.

Generic non-www/www redirects

If your server block covers multiple websites – e.g. a WordPress multisite network and you don’t want all of them to redirect to the same hostname, you can still do a universal check:

Redirect non-www to www:

if ($host !~ ^www\.) { return 301 $scheme://www.$host$request_uri; }

Redirect www to non-www

if ($host ~ ^www\.(?.+)$) { return 301 $scheme://$domain$request_uri; }

For the www/non-www redirects, it is worth mentioning again that using separate server blocks, where one use the return statement described at the top, is by far the most efficient.