Руководство по настройке редиректов в Nginx

Содержание

Nginx — один из самых распространённых веб-серверов, и настройка перенаправлений — рутинная часть работы с ним. Два основных инструмента — return и rewrite — часто путают, что приводит к неэффективным или нерабочим конфигурациям.

return vs rewrite

return (рекомендуется)

return 301 https://example.com;

rewrite (мощный, но медленнее)

rewrite ^/old-path/(.*)$ /new-path/$1 permanent;

💡 Правило

Используйте return везде, где возможно. Прибегайте к rewrite только когда нужны группы захвата regex или сложная трансформация URL.

Базовые примеры

301 постоянный редирект

server {
    listen 80;
    server_name old-domain.com;
    return 301 https://new-domain.com$request_uri;
}

302 временный редирект

server {
    listen 80;
    server_name example.com;
    location /maintenance {
        return 302 /maintenance.html;
    }
}

Перенаправление одной страницы

location = /old-page.html {
    return 301 /new-page.html;
}

HTTP на HTTPS

Рекомендуется: отдельные блоки server

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    # конфигурация сайта...
}

⚠️ Избегайте директивы if

В сообществе Nginx есть поговорка: «if — это зло». Директива if может вызвать непредсказуемое поведение в определённых контекстах. Используйте отдельные блоки server для HTTPS-перенаправлений.

Канонизация www

без www → www

server {
    listen 80;
    listen 443 ssl http2;
    server_name example.com;
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    return 301 https://www.example.com$request_uri;
}

www → без www

server {
    listen 80;
    listen 443 ssl http2;
    server_name www.example.com;
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    return 301 https://example.com$request_uri;
}

Перенаправление путей

# Перенаправление каталога с удалением префикса
location /blog/ {
    rewrite ^/blog/(.*)$ /articles/$1 permanent;
}

# Массовые перенаправления с map (эффективно для больших списков)
map $uri $new_uri {
    /old-page-1 /new-page-1;
    /old-page-2 /new-page-2;
}
server {
    if ($new_uri) { return 301 $new_uri; }
}

Regex-перенаправления

# Удаление расширения .html
location ~ ^(.+)\.html$ {
    return 301 $1;
}

# Удаление префикса с датой из URL
location ~ ^/\d{4}/\d{2}/\d{2}/(.+)$ {
    return 301 /$1;
}

Типичные ошибки

1. Цикл rewrite

# ❌ Бесконечный цикл
location /old/ {
    rewrite ^/old/(.*)$ /new/$1;
}

# ✅ Используйте флаг permanent или return
location /old/ {
    return 301 /new$request_uri;
}

2. Потеря строки запроса

# ❌ Строка запроса потеряна
location /old { return 301 /new; }

# ✅ Сохранение строки запроса
location /old { return 301 /new$is_args$args; }

3. Отсутствие SSL-конфигурации для HTTPS

Если вы перенаправляете HTTP → HTTPS, но не настроили блок HTTPS-сервера с валидным сертификатом, пользователи получат ошибку соединения. Всегда проверяйте, что блок HTTPS существует и сертификат действителен, прежде чем включать перенаправление.

Советы по производительности

После настройки перенаправлений проверьте их с помощью 301check.com.