Nginx — перенаправление на основе параметров строки запроса

Nginx — перенаправление на основе параметров строки запроса

У нас есть немного сложная проблема, которую нужно решить в нашей конфигурации nginx. В настоящее время у нас есть часть программного обеспечения, установленного в корневом каталоге документов. Это программное обеспечение использует единую точку входа (index.php) и строки запросов для отображения контента. Примеры URL-адресов:

/index.php?forums/forum-name.1
/index.php?threads/thread-name.1
/index.php?users/user-name.1

И т. д...

Теперь мы перемещаем это программное обеспечение в подкаталог /f/и устанавливаем новое программное обеспечение в корневой каталог документов. Это программное обеспечение ТАКЖЕ использует index.php (но без строк запросов). Поэтому нам нужно придумать набор правил перезаписи, чтобы ТОЛЬКО переписывать URL-адреса из старого программного обеспечения. В то же время мы также собираемся удалить index.php из URL-адресов. Вот набор примеров сопоставлений:

/index.php?forums/forum-name.1 --> /f/forums/forum-name.1
/index.php?threads/thread-name.1 --> /f/threads/thread-name.1
/index.php?users/user-name.1 --> /f/users/user-name.1

По сути, мне нужно перенаправить определенное подмножество запросов index.php (содержащее только ?forums, ?threads, ?users и т. д.), затем удалить часть index.php и отправить в каталог /f/.

Я игрался с этим все утро, но так и не смог заставить его работать так, как мне нужно.

решение1

Для управления сложными перенаправлениями, особенно когда задействованы строки запроса, mapможно использовать директиву.

Вы не можете сопоставить строку запроса (все, что ?начинается с ) в выражениях locationи rewrite, поскольку она не является частью нормализованного URI, однако $request_uriсодержит исходный запрос вместе со строкой запроса.

Сопоставление $request_uriможет быть проблематичным, если параметры отправлены в непоследовательном порядке, а также URI, содержащие странные символы, будут закодированы процентами.

Директива mapможет соответствовать строкам и/или регулярным выражениям. См.этот документдля получения подробной информации.

Например:

map $request_uri $redirect {
    default                                               0;
    ~*^/index\.php\?(?<suffix>(forums|threads|users).*)$  /f/$suffix;
    ...
}

server {
    ...
    if ($redirect) {
        return 301 $redirect;
    }
    ...
}

Всегда используйтеименованные захватыв mapрегулярном выражении блока. Отображенное выражение вычисляется в returnоператоре. Насколько я понимаю, каждый раз, когда nginxвстречается оператор, содержащийрегулярное выражение(например rewrite, некоторые locationблоки и некоторые ifоператоры), числовые захваты сбрасываются. Использованиеименованные захватыобеспечивает, чтобы они оставались в рамках returnзаявленного.

Видетьэта осторожностьоб использовании if.

Связанный контент