До основного вмісту

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.

← Назад до бази знань Поставити питання підтримці