К основному содержимому

rewrite и return в Nginx: как настроить редиректы без ошибок

Nginx · 29.09.2026

Редиректы в Nginx настраивают двумя способами: директивой return или директивой rewrite. Оба задаются внутри server block или location, описанных в статье про приоритет location в Nginx, но работают по-разному и одинаково легко ломают сайт при небрежной настройке.

return и rewrite: в чём разница

Директива return сразу останавливает обработку запроса и отдаёт клиенту код ответа и, при необходимости, адрес для редиректа. Это самый быстрый и предсказуемый способ сделать редирект: одна строка, минимум нагрузки на CPU.

Директива rewrite меняет сам URI запроса по регулярному выражению и, в зависимости от флага, либо продолжает обработку с новым URI внутри Nginx, либо отправляет клиенту HTTP-редирект. Rewrite гибче, но именно из-за этой гибкости чаще становится причиной циклов и неожиданного поведения.

Когда использовать return для простого редиректа

Если задача — просто отправить клиента на другой адрес без модификации пути, return всегда предпочтительнее rewrite. Официальная документация nginx.org прямо рекомендует return для редиректов, где не нужна подстановка по регулярному выражению.

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

Здесь $request_uri сохраняет исходный путь и query-параметры, поэтому example.com/page?id=5 остаётся example.com/page?id=5, а не превращается в редирект на главную страницу.

Синтаксис rewrite: флаги last, break, redirect, permanent

Директива rewrite принимает регулярное выражение, замену и необязательный флаг:

  • last — останавливает обработку текущего location и заново ищет location для нового URI.
  • break — останавливает обработку rewrite, но остаётся в том же location.
  • redirect — отправляет клиенту HTTP 302 с новым адресом вместо внутренней обработки.
  • permanent — отправляет клиенту HTTP 301 с новым адресом.

Без флага redirect или permanent rewrite не создаёт видимый браузеру редирект: новый URI обрабатывается внутри Nginx, и в адресной строке клиента остаётся старый адрес.

Частая ошибка: бесконечный цикл rewrite

Флаг last внутри location, который сам подходит под тот же шаблон rewrite, порождает бесконечный цикл: Nginx переписывает URI, заново ищет location, попадает в тот же блок, снова переписывает URI. Результат — ошибка rewrite or internal redirection cycle в error_log и 500-я ошибка на сайте.

Чтобы избежать цикла, проверяйте условием if ($uri !~ ...), что URI ещё не переписан, либо используйте break вместо last там, где переход в новый location не нужен. При проксировании на backend через reverse proxy на Nginx лишний rewrite часто вообще не нужен — proxy_pass справляется сам.

Коды 301 и 302: когда какой использовать

КодЗначениеКогда применять
301 Moved PermanentlyПостоянный редиректСмена домена, протокола, финальный переезд URL
302 FoundВременный редиректТехнические работы, A/B-тест, временная посадочная страница
307 Temporary RedirectВременный редирект с сохранением методаPOST-запросы, которые нельзя превращать в GET

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

Практические примеры редиректов

Три частых сценария редиректов на сайте, которые также стоит свериться со статьёй про SSL и Certbot в Nginx при переезде на HTTPS:

# редирект с www на домен без www
server {
    listen 80;
    server_name www.example.com;
    return 301 https://example.com$request_uri;
}

# редирект с http на https
server {
    listen 80;
    server_name example.com;
    return 301 https://example.com$request_uri;
}

# редирект старого URL на новый с сохранением параметров
rewrite ^/old-page$ /new-page permanent;

Чек-лист перед выкладкой редиректов

  1. Используйте return вместо rewrite, если не нужна подстановка по регулярному выражению.
  2. Указывайте $request_uri, чтобы не терять путь и query-параметры при редиректе.
  3. Проверяйте на бесконечный цикл: nginx -t не всегда находит эту ошибку, тестируйте curl -I.
  4. Выбирайте 301 для постоянных переездов и 302 для временных.

Return и rewrite решают одну задачу — перенаправление трафика — но с разной ценой: return быстрее и надёжнее для прямых редиректов, rewrite нужен там, где путь запроса действительно меняется по шаблону. Тестируйте каждый новый редирект командой curl -I перед тем, как выкладывать его в production.

← Назад в базу знаний Задать вопрос поддержке