Правила rewrite URL в NGINX

NGINX позволяет изменять URL-запросы с помощью директив rewrite и return. Это используется для перенаправлений, очистки URL, миграции структуры сайта и обработки маршрутов приложений.

Директива return

Самый простой способ сделать редирект — использовать return.

server {
    listen 80;
    server_name old-site.com;

    return 301 https://new-site.com$request_uri;
}

В этом примере:

  • 301 означает постоянный редирект

  • $request_uri сохраняет путь и параметры исходного URL

Если пользователь откроет:

http://old-site.com/blog/post

он будет перенаправлен на:

https://new-site.com/blog/post

Директива return работает быстрее и проще, чем rewrite, поэтому её рекомендуют использовать для обычных редиректов.

Директива rewrite

rewrite используется для более сложных преобразований URL.

Базовый синтаксис:

rewrite regex replacement [flag];

Где:

  • regex — регулярное выражение для поиска

  • replacement — новый URL

  • flag — поведение после обработки

Пример:

location /old/ {
    rewrite ^/old/(.*)$ /new/$1 last;
}

Запрос:

/old/page.html

будет преобразован в:

/new/page.html

Флаг last заставляет NGINX повторно обработать новый URI.

Флаги rewrite

NGINX поддерживает несколько флагов для управления поведением rewrite.

last

Повторно запускает поиск подходящего location.

rewrite ^/old/(.*)$ /new/$1 last;

break

Останавливает обработку rewrite внутри текущего блока.

rewrite ^/old/(.*)$ /new/$1 break;

redirect

Выполняет временный редирект 302.

rewrite ^/docs/(.*)$ /manual/$1 redirect;

permanent

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

rewrite ^/docs/(.*)$ /manual/$1 permanent;

Перенаправление HTTP на HTTPS

Частая задача это перенаправление всего HTTP-трафика на HTTPS.

server {
    listen 80;
    server_name example.com www.example.com;

    return 301 https://$host$request_uri;
}

После этого любой HTTP-запрос автоматически перейдёт на HTTPS.

Редирект без www

server {
    listen 80;
    server_name www.example.com;

    return 301 https://example.com$request_uri;
}

Или наоборот:

server {
    listen 80;
    server_name example.com;

    return 301 https://www.example.com$request_uri;
}

Внутренний rewrite без изменения URL

Rewrite можно использовать без изменения адреса в браузере.

location / {
    rewrite ^/profile/(.*)$ /user.php?id=$1 last;
}

Если пользователь откроет:

/profile/15

NGINX internally обработает запрос как:

/user.php?id=15

Но в браузере останется исходный URL.

Очистка URL

Rewrite часто используют для создания "красивых" URL.

Исходный URL:

/products.php?id=25

Новый URL:

/products/25

Конфигурация:

location / {
    rewrite ^/products/([0-9]+)$ /products.php?id=$1 last;
}

Значение $1 содержит часть URL, найденную регулярным выражением.

Использование try_files

Во многих современных приложениях вместо rewrite используют try_files.

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

NGINX:

  1. Проверяет существование файла

  2. Проверяет существование директории

  3. Если ничего не найдено — передаёт запрос в index.php

Такой подход часто используется в Laravel, WordPress и SPA-приложениях.

Rewrite для Laravel

Типичная конфигурация Laravel:

server {
    listen 80;
    server_name example.com;

    root /var/www/project/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Все маршруты Laravel будут автоматически передаваться в index.php.

Rewrite с параметрами

Можно извлекать части URL через регулярные выражения.

rewrite ^/category/([^/]+)/([^/]+)$ /search.php?cat=$1&item=$2 last;

Запрос:

/category/books/php

станет:

/search.php?cat=books&item=php

Проверка конфигурации

После изменения конфигурации нужно проверить синтаксис:

sudo nginx -t

Если ошибок нет, применяем настройки:

sudo systemctl reload nginx

Частые ошибки

Бесконечные циклы rewrite возникают, когда правило повторно обрабатывает уже изменённый URL. В таких случаях используют break или более точные регулярные выражения.

Также важно помнить, что location в NGINX работает только с URI без query-параметров.

Похожие статьи

Декодирование JSON из HTTP-ответов в Laravel

Как Laravel обрабатываются JSON-ответы HTTP-клиента и какие возможности дают флаги декодирования JSON. Рассматриваются ошибки декодирования, работа с большими числами и настройка флагов по умолчанию.

Как отключить SELinux на Ubuntu, CentOS, Debian и RHEL

Подробная инструкция по проверке, временной и постоянной деактивации SELinux на популярных Linux-дистрибутивах: Ubuntu, Debian, CentOS и RHEL. Объяснены способы через консоль и конфигурационные файлы.