2016-01-05 5 views
0

Я пытаюсь создать nginx 301-redirect wordpress-style foo.com/?p=123 ссылки на фиксированные URL-адреса.Безопасный/эффективный способ перенаправления nginx /? P = 123 ссылок на стиль

От If is evil и других документов, я понимаю, что наступит if заявлений являются единственным способом для перенаправления на основе параметров, и я обнаружил, что конфигурация, как это кажется, чтобы получить работу:

location/{ 
    root /usr/share/nginx/html; 
    index index.html index.htm; 
} 

location =/{ 
    root /usr/share/nginx/html; 
    index index.html index.htm; 

    if ($arg_p = 4) { return 301 /2012/12/hello-world; } 
    if ($arg_p = 15) { return 301 /about;    } 
    # ... a few hundred more lines like this 
} 

Однако я предположим, что с помощью такого типа config nginx придется вспахивать все эти операторы if, чтобы разрешить запросы foo.com/ верхнего уровня, которые, по-видимому, не идеальны.

Что такое «правильный» способ жесткого кодирования большого списка таких перенаправлений, минимизируя опасность/стоимость if заявлений?

ответ

1

Первой хорошей идеей было бы перевести правила переадресации в отдельный файл. Это сделает основную конфигурацию более читаемой. Файл с правилами затем может быть включен в директиву include.

Еще одна хорошая идея - использовать map вместо if, так как он имеет более аккуратный синтаксис для определения длинных списков.

Предположим, вы решили ввести правила в /path/to/redirect/rules.conf. Содержимое этого файла, то будет выглядеть следующим образом:

# Each map defines the set of rules for one set of conditions. 
# The blocks must be sorted in order of priority: every next 
# map block has a higher priority than the previous one. 
map $arg_p $p_condition { 
    default ""; 

    4    /2012/12/hello-world; 
    15    /about; 

    # You can use regular expressions 
    ~^1[6-9]$  /some/page; 
} 

# By combining the condition variables you can implement 
# some sort of and/or/not logic in your rules 
map "${arg_p}#${arg_q}" $pq_condition { 

    # Note that it is necessary to inherit the result 
    # of the previous map block to preserve them. And this 
    # is where the priority of the blocks comes from 
    default $p_condition; 

    # The values of p _and_ q are 4 and 15 
    4#15   /2012/12/hello-world; 

    # The value of p is 5 _or_ the value of q is 16 
    ~"^5#.*"  /another/page; 
    ~"^.*?#16"  /another/page; 

    # The value of p is _not_ 8 _and_ the value of q is 30 
    ~"^[^8]#30" /the/very/special/page; 
} 

# The final block is of the highest priority. It defines 
# the variable, which value will be used as the URL for redirection 
map $args $url_to_redirect_to { 

    # Don't forget this important line 
    default $pq_condition; 

    # Here's another type of condition: check if the t variable 
    # is present in the list of GET paramters 
    ~^(&|\?)t=.*$ /yet/another/page; 
} 

Теперь все, что осталось сделать, это использовать определенные правила в основной конфигурации:

# Note that map directives must be placed out of the `server` block 
include /path/to/redirect/rules.conf; 

server { 
    ... 

    location =/{ 
     ... 

     if ($url_to_redirect_to != "") { 
      rewrite^$url_to_redirect_to? permanent; 
     } 

     ... 
    } 

    ... 
} 

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

+0

Выглядит отлично, спасибо! – fenomas

 Смежные вопросы

  • Нет связанных вопросов^_^