У меня сейчас задача сделать большую миграцию сайта. И у меня в config большое количество редиректов. Но я не могу понять, почему одно перенаправление вызывает второе перенаправление в цепочке. Даже если любые другие редиректы прокомментированы / отключены.
Итак, моя конфигурация для местоположения:
server {
...
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~* /index.php {
if ($args ~ "^page=flights&start_city=([\+\w\d\s]*)(&.*)?$"){
return 301 $scheme://$server_name/flights?departure_city=$arg_start_city;
}
if ($is_args){
return 301 $scheme://$server_name/$1;
}
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
Чего я жду? Я ожидаю, что старые ссылки вроде
https://example.com/index.php?page=flights&start_city=Berlin&s_loc_lat=&s_loc_long=
Становиться:
https://example.com/flights?departure_city=Berlin
И при этом ссылки вроде:
https://example.com/index.php?someoldpar=someoldkey&someoldpar2=someoldkey2
Становиться:
https://example.com/
Что я получил при тестировании этого конфига?
. Я получил эту цепочку перенаправления для первой ссылки:
1. GET https://example.com/index.php?page=flights&start_city=Berlin&s_loc_lat=&s_loc_long=
2. 301 https://example.com/flights?departure_city=Berlin
3. 301 https://example.com/
Как исключить шаг 3 для уже перенаправленных ссылок? Лаварел под бэкэндом.
Ваш try_files
оператор перезаписывает URI на /index.php
и добавляет строку запроса. Ваш if ($is_args)
оператор перенаправляет любой URI со строкой запроса. У вас есть петля перенаправления.
В location ~* /index.php
блок не может отличить исходный запрос, содержащий index.php
и результат try_files
дефолт.
Вы должны выполнить свои тесты на $request_uri
переменная, которая всегда будет содержать исходный запрос вместе со строкой запроса. Вы можете использовать if
или map
. С более чем несколькими регулярными выражениями map
является предпочтительным решением.
Например:
map $request_uri $redirect {
default 0;
~^/index.php\?page=flights&start_city=(?<startcity>[\+\w\d\s]*)(&.*)?$ /flights?departure_city=$startcity;
~^/index.php\? /;
}
server {
...
if ($redirect) {
return 301 $redirect;
}
Вы можете удалить свой location ~* /index.php
блок, так как он больше не требуется. Регулярные выражения оцениваются по порядку до тех пор, пока не будет найдено правило сопоставления, поэтому упорядочивайте правила, начиная с наиболее конкретных и наименее конкретных последних. Используйте именованные захваты, так как числовые захваты могут выйти за пределы области видимости. Вам не нужно указывать схему или доменное имя, если они совпадают. В map
директива находится за пределами блока server. Видеть этот документ для подробностей.