Используемые термины: NGINX, http, https, веб-сервер.
В данной инструкции мы рассмотрим, в большей степени, перенаправления запросов на другие страницы с помощью NGINX. Также мы немного разберем проксирование и перенаправление на другие файлы.
Настройки необходимо вносить в файлах конфигураций виртуальных доменов. В Linux на основе RPM (CentOS, Red Hat), как правило, они расположены в директории /etc/nginx/conf.d/. В Linux на основе Deb (Ubuntu, Debian) — в директории /etc/nginx/sites-enabled/. Во FreeBSD все в одном файле — /usr/local/etc/nginx/nginx.conf.
Саму настройку на перенаправление в NGINX можно прописать несколькими способами.
1. Первый:
rewrite ^ https://$host$request_uri? <флаг>;
* $host — имя хоста из запроса, если отсутствует — имя в поле «Host» заголовка, если тоже отсутствует — имя сервера; $request_uri — первоначальный запрос с аргументами (все, что идет после доменного имени).** где флаги могут быть следующие:
2. Второй:
return <код> https://$host$request_uri;
* где коды могут использоваться любые, но чаще всего — 301, 302, 404.
Есть различные мнения, какой из методов лучше и безопаснее, поэтому каким воспользоваться — решать по ситуации. В данных примерах используются оба варианта.
После внесения изменений, необходимо проверить их корректность:
И для их применения перезапустить веб-сервер:
systemctl restart nginx
service nginx restart
* в первом примере перезапуск выполняется на новых системах Linux. Второй пример — на устаревших или FreeBSD.
Проверяя редиректы в браузере, следует учесть, что настройки могут кэшироваться. Для обновления кэша используйте комбинацию Ctrl + F5. Если и это не помогает, закрывайте вкладку и открывайте новую.
Пример конфигурации для перенаправления запросов на другой порт — с 80 (http) на 443 (https):
server { listen 80; server_name domain.ru www.domain.ru; return 301 https://$host$request_uri;}
* в данном примере для всех обращений к сайту domain.ru по 80 порту (http) будет работать редирект на 443 порт (https) с кодом 301 (для склеивания доменов).
Также мы можем добавить условие, чтобы не перенаправлять на https для определенных ссылок, например:
server { listen 80; server_name domain.ru www.domain.ru; if ($uri !~ /page.html){ return 301 https://$host$request_uri; }}
* в данном примере запрос на страницу /page.html будет открыт по http.
server { … server_name domain1.ru; return 302 http://domain2.ru$request_uri;}
server { … server_name domain.ru; return 301 http://www.$host$request_uri;}
Конкретный домен:
server { … server_name www.domain.ru; return 301 $scheme://domain.ru$request_uri;}
Все домены, которые обслуживает nginx:
server { … server_name «~^www\.(.*)$»; return 301 $scheme://$1$request_uri;}
Данная настройка позволит перевести все запросы с /index.php на корневой адрес /:
server { … if ($request_uri ~ «^(.*)index\.(?:php|html)») { return 301 $1; }}
Если обращение к веб-серверу идет по IP-адресу или домену, который не прописан в конфигурационном файле, можно перенаправить весь трафик на домен по умолчанию:
server { listen 80 default_server; return 302 https://welcome.domain.ru$request_uri;}
или независимо от протокола:
server { listen 80 default_server; return 302 $scheme://welcome.domain.ru$request_uri;}
server { listen 443 default_server; return 302 $scheme://welcome.domain.ru$request_uri;
ssl on; ssl_certificate /etc/nginx/ssl/cert.pem; ssl_certificate_key /etc/nginx/ssl/cert.key;}
* $scheme позволяет перевести запрос на тот же протокол (http или https), по которому он был инициирован.* если nginx должен слушать и обрабатывать запросы по https, необходимо указывать в настройках пути к сертификатам.
В данном случае мы переводим все запросы по IP-адресу на конкретный домен:
server { listen 80; server_name 192.168.1.15; return 301 http://site.ru$request_uri;}
* при отправке http-запроса на сервер 192.168.1.15 по IP-адресу, он будет переведен на домен site.ru.
server { … server_name domain domain.*; return 301 https://$host$request_uri;}
Это скорее не перенаправление, а алиас или rewrite. Позволяет по запросу одного из файлов, отдать другой:
server { … location = /robots.txt { rewrite ^/robots.txt$ /robots2.txt; }}
* в данном примере по запросу robots.txt, сервер отдаст содержимое robots2.txt.
Перенаправить запрос на другой сервер при обращении по url page1:
server { … server_name domain1.ru; location ~ ^/page1/(.*)$ { return 301 $scheme://domain2.ru/$1; }}
* в данном примере для всех запросов, начинающихся на /page1/… будет работать перенаправление на другой домен domain2.ru.
1. Убрать слеш в конце url
server { … if (!-f $request_filename ) { rewrite ^/(.*)/$ /$1 permanent; }}
2. Добавить слеш в конце url
server { … if (!-f $request_filename ) { rewrite ^(.*[^/])$ $1/ permanent; }}
Для перенаправления запроса, где в URL есть полное название файла скрипта (с расширением) используем конфигурацию:
server { … if ($request_uri ~ «^(.*)\.(?:php|html)») { return 301 $1; }}
* в данном случае все запросы, которые заканчиваются на .php или .html, будут перенаправляться на страницы без данных расширений.
Для примера, запрос http://site-example.ru/page.php будет переведен на http://site-example.ru/page.
Нам может понадобиться перенаправлять запросы с одной страницы сайта на другую. Приведем примеры, как это сделать с помощью return и rewrite.
а) с помощью rewrite:
server { … rewrite ^/page1$ /page2 permanent;}
б) с помощью return:
server { … location = /page1 { return 301 /page2; }}
Иногда нужно удалять часть url. Это можно сделать следующими способами:
server { … rewrite /deleted-url/(.*) /$1 permanent;}
или:
server { … if ($request_uri ~ «/deleted-url/(.*)») { return 301 $1; }}
* в данном примере из url мы удалим deleted-url/.
Предположим, что нам нужно обращаться к скриптам на сервере, но без прописывания в URL .php на конце. Запрос будет выглядеть, примерно, http://url/. Чтобы nginx перекинул запрос на url.php вставляем следующее:
server { … if (!-e $request_filename){ rewrite ^(.*)$ /$1.php; }}
* в данном примере мы проверяем наличие файла, к которому идет обращение. И если его нет, то происходит замена адреса на такое же имя файла с .php на конце.
Данное действие не является редиректом, но близко по смыслу — NGINX проверяет наличие файла скрипта, к которому идет обращение, и если его нет, переводит запрос на другой файл. Как правило, это используется для того, чтобы перевести все обращения на файл index.php.
server { … location / { try_files $uri $uri/ /index.php?$query_string; } …}
* в данном примере мы скажем веб-серверу все запросы обрабатывать с помощью файла index.php в корневой директории.
Проксирование, в отличие от редиректа, не передает инструкции браузеру перейти на другой url — NGINX сам выполняет http-запрос по другому адресу и возвращает готовый ответ. Эта возможность может применяться для внутреннего распределения серверных ресурсов.
Хоть это и не совсем редирект, рассмотрим примеры его настройки, так как очень часто нужно не перенаправление, а, как раз, обратное проксирование.
Пример внутреннего перенаправления http-запроса на другой веб-сервер:
…location / { proxy_pass $scheme://192.168.0.15:8080/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}
* в данном случае, принимать запросы от браузера и отвечать на них будет NGINX, а сама обработка будет выполняться на сервере с IP-адресом 192.168.0.15 на порту 8080.
Использование NGINX в качестве http-прокси:
server { … server_name site1.ru www.site1.ru; location / { proxy_pass http://192.168.1.21/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}
server { … server_name site2.ru www.site2.ru; location / { proxy_pass http://192.168.1.22/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}
* в данном примере запросы на site1.ru будут перекинуты на сервер 192.168.1.21, а запросы на site2.ru — 192.168.1.22.
HTTP proxy с авторизацией (если удаленный веб-сервер требует аутентификации):
server { … location / { proxy_pass http://10.10.10.10/page/; proxy_set_header Authorization «Basic dGVzdDp0ZXN0»; … }}
* где 10.10.10.10/page — страница, на которую будут перекинуты запросы; dGVzdDp0ZXN0 — логин:пароль test:test, закодированные в формате base64.
Выше мы рассмотрели пример перенаправления запроса по части веб-адреса. По схожему сценарию мы можем делать проксирование:
server { … location ~ ^/page1/(.*)$ { proxy_pass $scheme://10.10.10.10/$1; }}
* и так, в данном примере при обращении по адресу site.ru/page1/<что-то еще>, nginx сделает внутренний запрос на сервер 10.10.10.10 по адресу 10.10.10.10/<что-то еще> и вернет готовый ответ.
Мы можем сделать так, что при переходе по одному адресу у нас будет открываться совершенно другой сайт:
server { … location / { proxy_pass https://www.admins24.com; proxy_set_header Host www.admins24.com; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}
* в данном случае мы при обращении к нашему серверу будем попадать на сайт https://www.admins24.com. Обратите внимание, что в proxy_set_header мы передаем хосту его имя — в противном случае, как правило, другой сервер вернет ошибку. Также мы не указываем proxy_redirect, иначе, nginx будет переводить запросы на реальный сайт (отправлять инструкции браузеру перейти на него), а не тот, что мы используем за http-прокси.
Если при проксировании хост возвращает инструкцию браузеру для выполнения редиректа, обозреватель может сменить адрес сайта. Это особенно не удобно, когда проксирование мы выполняем на другой сайт. Чтобы отловить редиректы и заменить их своими значениями, мы должны воспользоваться опцией proxy_redirect. Рассмотрим ее применение для предыдущего примера, когда мы проксировали запрос на сайт www.admins24.com:
server { listen 80; server_name admins24.local www.admins24.local; location / { proxy_pass https://www.admins24.com; proxy_set_header Host www.admins24.com; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect https://admins24.com/url1 http://admins24.local/url2; proxy_redirect https://admins24.com/ http://admins24.local/; }}
* в конкретном случае мы проксируем запросы http://admins24.local на сайт www.admins24.com, но если он вернет инструкцию для редиректа https://admins24.com/url1, в браузере он должен быть заменен на http://admins24.local/url2. А также любое перенаправление для https://admins24.com/ будет заменено на http://admins24.local/.
В чем принципиальная разница между ответом с кодом 301 и 302? Для обычного посетителя сайта разницы нет. А вот для поискового робота разница огромная.
301-й редирект говорит о склеивании страниц. Это означает для поисковика то, что старая и новая страницы — это одно и то же. Таким образом, результаты ранжирования необходимо сохранить для новой страницы.
302-о перенаправление просто говорит о том, что нужно перейти по другому адресу. Поисковый робот не сохраняет результат выдачи для новой страницы, индексируя его с нуля.
Продолжая использовать данный сайт вы принимаете политику конфиденциальности и cookies