Редиректы в nginx
Если у вас на сайте есть 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
После переноса одного сайта на 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 в запросе, он может отличаться от первоначального, например, при внутренних редиректах или при использовании индексных файлов.
Начнем с вопроса, что вообще это такое 301 редирект ? Редирект (Redirect) – это перенаправление пользователей с одного (сайта) на другой, либо с одной определенной страницы на другу. Используется он довольно таки часто и сейчас мы разберемся, как его настроить и для чего он нужен.
Для чего нужен 301 редирект?Перейдем непосредственно к настройке редиректа 301 для разных серверов.
Как настроить 301 редирект.htaccess?Если вы используете сервер Apache, то вы без проблем сможете сделать 301 редирект с помощью файлов.htaccess или httpd.conf. Необходимо так же включить модули, для поддержки директив.:
Директивы:- mod_alias (Redirect, RedirectPermanent и RedirectMatch);
- mod_rewrite (RewriteRule).
Используем директивы Redirect или RedirectPermanent, для настройки 301 редиректа
co старой страницы на новую страницу, нового сайта.
Redirect 301 /old-page.html http://new-domain.ru/new-page.html
или
Redirect permanent /old-page.html http://new-domain.ru/new-page.html
или
RedirectPermanent /old-page.html http://new-site.ru/new-pagehtml
Недостатком этого метода является то, что все страницы которые необходимо перенаправлять, нужно прописывать одну за другой (последовательно). Используем директиву RedirectMatch, для тех же целей.
RedirectMatch /(.*)\.php$ /$1.aspx
Данный метод можно использовать при переносе сайта с PHP движка на ASP.
Переадресация домена с www префиксом на без www в.htaccess.Как уже говорилось склеивать домены с www и без, необходимо для того, что бы получить главное зеркало сайта. Если в выдаче будет два , то поисковые системы могут наложить санкции на сайт, так как они будут воспринимать их как два разных сайта.
Используем директивы RewriteRule для редиректа 301
, домена с www префиксом на без него. Как пример будем использовать наш сайта:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.loleknbolek\.com$
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTP_HOST} ^loleknbolek\.com$
RewriteRule ^(.*)$ https://сайт/$1
Старайтесь сразу при создании сайта делать домен без www. Если вы купили сайт, то сразу проверяйте есть ли зеркала, так как я говорил, наличие зеркал сайта в поисковой системе, может негативно сказаться на вашем ресурсе.
Как настроить 301 редирект nginx?Давайте рассмотрим пример переадресации для сайта с www на без www. Пример для нашего сайта:
if ($host = ‘www.www.сайт’) {
rewrite ^(.*)$ https://сайт$1 permanent;
}
Можно еще попробовать вот так:
server {
server_name сайт;
rewrite ^ https://сайт$request_uri? permanent;
}
server {
server_name www.сайт;
…. основная конфига. …
}
Настраиваем с помощью использования скриптов, редирект делаем на новый адрес сайта, со старого.
PHP редирект: ASP редирект:
private void Page_Load(object sender, System.EventArgs e)
{
Response.Status = “301 Moved Permanently”;
Response.AddHeader(“Location”,“http://www.new-url.com”);
}
JSP (Java) редирект
$q = new CGI;
print $q->redirect(“http://www.new-url.com/”);
Ruby on Rails
def old_action
end
def old_action
headers[“Status”] = “301 Moved Permanently”
redirect_to “http://www.new-url.com/”
end