Преобразование правил перезаписи модов, которые используют% (QUERY_STRING), в формат перезаписи NGINX? - PullRequest
2 голосов
/ 14 марта 2010

Последние несколько дней я застрял, пытаясь преобразовать следующее правило перезаписи Apache / Mod_Rewrite в формат NGINX. Кто-нибудь знает, где я иду не так?

mod_rewrite:

RewriteCond %{QUERY_STRING} topic=([0-9]+)
RewriteRule /forum/index\.php /forum/vbseo301.php?action=thread&oldid=%1 [L]

NGINX:

location /forum/index.php {
           if ($args ~ "topic=([0-9]+)"){
                        rewrite ^/forum/index\.php?topic=(.+)$ /forum/vbseo301.php?action=thread&oldid=$1 last;
                        }
        }

Ответы [ 3 ]

0 голосов
/ 16 марта 2010

Из предоставленных вами данных я согласен, что единственный способ - использовать if (несмотря на то, что if вообще не рекомендуется). Попробуйте это:

location /forum/index.php {
  if ($arg_topic != "") {
    rewrite ^ /forum/vbseo301.php?action=thread&oldid=$arg_topic? break;
  }
}

Я оставлю свой предыдущий ответ, так как он может помочь кому-то еще.

Простой пример, чтобы убедиться, что это работает

Я привел более простой пример, чтобы показать, что это работает. Вот фрагмент конфигурации Nginx:

location /index.html {
    if ($arg_topic != '') {
        rewrite ^ /vv.html?t=$arg_topic? break;
    }
    ssi on;
    root /home/alaz;
}

location /vv.html {
    ssi on;
    root /home/alaz;
}

index.html содержание:

<b>index</b>
<br/>
topic: <!--#echo var="arg_topic" -->

vv.html содержание:

<b>vv</b>
<br/>
topic: <!--#echo var="arg_topic" -->
<br/>
t: <!--#echo var="arg_t" -->

Теперь перезагрузите Nginx и наведите ваш браузер на http://hostname/index.html сначала и http://hostname/index.html?topic=11 после этого.

0 голосов
/ 13 марта 2013

Кажется, многие люди все еще просматривают этот вопрос. Надеюсь, мой ответ поможет!

location /forum/index.php {
  if ($args ~ "topic=([0-9]+)"){
    rewrite ^/forum/index\.php$ /forum/vbseo301.php?action=thread&oldid=$arg_topic? last;
  }
}

Проверено и все работает. Несколько критических, но тонких исправлений в строке перезаписи:

  1. Я удалил часть строки запроса «? Topic = (. +)» Из старого URL-адреса, потому что правило перезаписи nginx не совпадает со строками запроса (также называемыми args в nginx). Он только пытается соответствовать PATH. ссылка
  2. Аргумент topic = xxxx автоматически сохраняется в nginx в этой переменной: $ arg_topic. Так что я могу просто вставить "oldid = $ arg_topic" в новый URL. ссылка
  3. Я поставил знак вопроса "?" в конце нового URL, чтобы nginx не пытался присоединить строку запроса из старого URL. По умолчанию nginx присоединяет всю строку запроса из старого URL.
0 голосов
/ 15 марта 2010

Это не отвечает на вопрос - пожалуйста, прочитайте комментарий с дополнительной информацией Я оставляю этот ответ для размещения других вариантов переписывания, пригодных для других ситуаций.

Вы можете сделать это проще:

# At "server" level, NOT in "location"
rewrite ^/forum/index.php
         /forum/vbseo301.php?action=thread&oldid=$arg_topic?
        last;

? Суффикс говорит Nginx не добавлять оригинальные аргументы к новому URL.

Sidenote

Кстати, если вы делаете статическое сопоставление одного набора идентификаторов другому, есть более эффективное решение:

http {
  map $arg_topic $new_topic_id {
    default 1;
    2 3;
    4 65;
  }

  server {
    # some directives (server_name, listen, etc.) omitted

    rewrite ^/forum/index.php /forum/new.php?topic=$new_topic_id? last;

    # locations omitted
  }
}

map принимает первый параметр (в данном случае topic из строки запроса) и просматривает таблицу. Затем он присваивает результат второму параметру (new_topic_id). Два преимущества:

  • Поиск очень эффективен, так как Nginx создает хеш-таблицу.
  • Поиск происходит только тогда, когда вы собираетесь использовать new_topic_id (ленивая оценка)
...