mod_rewrite удаляет переменную GET

#apache #mod-rewrite #get

#apache #mod-переписать #получить

Вопрос:

Я пытаюсь взять

example.com/home?lang=framp;foo=bar

и перенаправляет на

example.com/fr/home ?foo=bar

Я пытался

     RewriteCond %{QUERY_STRING} lang=([a-z]{2})amp;?
    RewriteRule ^(.*) /%1/$1 [R=307]
  

но я получаю цикл перенаправления.
Это потому, что lang=fr не удаляется из строки запроса после того, как ‘fr’ перемещается в начало строки запроса. Это приводит к:

example.com/fr/fr/fr/fr/fr/fr/fr/fr/fr /….

Я могу использовать

     RewriteRule ^(.*) /%1/$1? [R=307]
  

но это также удаляет foo=bar из строки запроса, которую я хочу сохранить нетронутой

Я не могу найти способ удаления только одной переменной из строки запроса. Я уверен, что есть простое решение, но Google не помог. Спасибо

Ответ №1:

В дополнение к ответу @whoisgregg ( 1), который является хорошей адаптацией из apache wiki. Правила там не совсем приятные (например, управление доступом по строке запроса на этой странице не будет сопротивляться небольшому urlencoding).

У нас есть рабочее решение для тестового примера, но некоторые расширенные тесты могут завершиться неудачей:

 RewriteCond %{QUERY_STRING} ^(.*)lang=([a-z]{2})amp;?(.*)$
RewriteRule (.*) /%2/$1?%1%3 [R=307]

foo.php?foo=baramp;novlang=framp;toto=titi => /fr/foo.php?foo=baramp;novtoto=titi
  

Здесь lang= часть обнаружена, но если какой-либо параметр заканчивается на lang, у вас возникнет проблема.

Итак, нам нужно какое-то исправление, я работал над этой темой на этой неделе, и вот лучшая версия, я думаю:

 RewriteCond %{QUERY_STRING} (.*)(^|amp;|&| )lang(=|=)([^amp;] )(.*)$
RewriteRule (.*) /%4/$1?%1%5 [R=307]

foo.php?foo=baramp;novlang=framp;toto=titi => not matched (normal, no lang=)
foo.php?foo=baramp;lang=framp;toto=titiamp;b=a => fr/foo.php?foo=baramp;toto=titiamp;a=b
  

Единственная проблема, ожидающая решения здесь, заключается в том, что lang может быть частично или полностью закодирован url и не будет обнаружен, но это редкий случай. Я также удалил контроль наличия только 2 символов в значении lang. Я думаю ([^amp;] ) , что лучше, это означает, что все символы, пока я не совпаду amp; .

Ответ №2:

Это вариант метода из apache wiki, который должен сделать трюк:

 RewriteCond %{QUERY_STRING} ^(.*)lang=([a-z]{2})amp;?(.*)$
RewriteRule (.*) /%2/$1?%1%3 [R=307]
  

Комментарии:

1. @whoigregg: хорошо, но я добавил некоторые улучшения, см. Мой ответ.