Web
July 30, 2020

Nginx - обслуживание множества редиректов с помощью Nginx map

"Ткнул" в гугле, а получил 404 "страница не найдена", почему так?

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

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

Выход из данной ситуации логичен - нужен 301 (перманентный = постоянный) редирект на новый адрес страницы.

Предположим, у нас был раздел /nashy-raboty и мы сменили его адрес на /portfolio (что более логично и понятнее), но наша CMS не обеспечивает перенаправление со старого адреса на новый.

Выход - использовать редиректы на уровне веб сервера Nginx

Редирект в Nginx "в лоб"

В конфиге своего сайта мы можем написать что-то вроде

server {
# Тут про имя сервера и порт

location /nashy-raboty {
  return 301 /portfolio;
}

# Тут целевые локации вашего приложения
}

И это будет работать, при переходе на старый url пользователь будет перекинут на новый и он увидит, то что хотел.

Роботы поисковиков зафиксируют 301 редирект (страница перемещена навсегда) и учтут это в своей индексации.

А если надо сделать 100500 редиректов?

Очевидно, что при большом количестве редиректов обслуживать конфигурацию nginx будет непросто и утомительно

Выход использовать конструкцию map

map $request_uri $redirected_url {
  default "none";
  /nashy-raboty /portfolio;
  /work /works; 
}

server {
# Тут про имя сервера и порт

if ($redirected_url != "none") {
	rewrite ^ $redirected_url permanent;
	}

# Тут целевые локации вашего приложения
}

Как это работает?

map $uri $redirected_url {
  default "none";
  /nashy-raboty /portfolio;
  /work /works; 
}

Задавать значение для переменной $redirected_url в зависимости от значения в переменной $uri

$uri - встроенная переменная nginx которая содержит хвост запроса пользователя

Получается, если запрос будет на /nashy-raboty, то в $redirected_url запишется значение /portfolio аналогично для второго правила с /work -> /works если соответствия в map найдено не будет, то используется default = "none"

if ($redirected_url != "none") {
	rewrite ^ $redirected_url permanent;
	}

Далее, если $redirected_url отличается от значения по умолчанию, то надо выполнить редирект на URL записанный в значении переменной $redirected_url