RewriteRule и query_string
версия для печатиПонадобилось мне после слияния сайтов описать правило для mod_rewrite типа
http://sub.site.ru/?id=NN -> http://site.ru/NNСогласен, обычно наоборот пишут, но надо мне так.. Делаю все по мануалу Apache и ничего не получаю. Порылся в инете и нашел решение, которое работало, хотя в разрез с документацией. Еще полчаса в поисках объяснения этого явления привели меня к статье на английском как раз о том, как mod_rewrite реально работает с query_string. Собственно вольный перевод прилагается.
Оригинал здесь. Статья написана в январе 2009, но актуальна до сих пор.
На первый взгляд, способ, которым mod_rewrite работает со строками GET-запроса, слегка озадачивает. Из оффициальной документации по RewriteRule:
флаг qsappend|QSA (query string append - дописать строку запроса)Этот флаг указывает движку rewrite-a дописать параметры GET-запроса к существующей строке, вместо того, чтобы заменить их. Используйте этот флаг, когда хотите добавить свои парамеры в строку запроса через RewriteRule.
Давайте попробуем сделать редирект на страницу, в зависимости от строки запроса. Для примера возьмем адрес типа http://mydomain.site/page.php?id=NN, где NN - число. Правило rewrite-а должно бы выглядеть так:
RewriteCond %{QUERY_STRING} ^id=([0-9]*)$RewriteRule ^page\.php$ http://mydomain.site/page/%1.php [R=302,L] Согласно оффициальной документации, нам следует ожидать следующее поведение: /page.php?id=37 -> http://mydomain.site/page/37.php
/page.php?id=40 -> http://mydomain.site/page/40.php
# и так далее
Как бы там ни было, если вы не допишете что-то новое, то исходная строка запроса (GET-параметры) пройдет через правила без изменений:
/page.php?id=37 -> http://mydomain.site/page/37.php?id=37/page.php?id=40 -> http://mydomain.site/page/40.php?id=40
# и так далее
Если вы хотите убрать исходную строку запроса, нужно в конце подстановки писать знак вопроса. Давайте назовем его "флагом отмены строки запроса":
RewriteCond %{QUERY_STRING} ^id=([0-9]*)$RewriteRule ^page\.php$ http://mydomain.site/page/%1.php? [R=302,L] Вот с этим "флагом" новый URL будет выглядеть, как ожидается.
Краткая справка по работе со строкой запроса в RewriteRule:
Сохранить исходный запрос (поведение по умолчанию)RewriteRule ^page\.php$ /target.php [L]
# из http://example.com/page.php?foo=bar
# в http://example.com/target.php?foo=bar
Удалить исходный запрос
RewriteRule ^page\.php$ /target.php? [L]
# из http://example.com/page.php?foo=bar
# в http://example.com/target.php
Заменить исходный запрос
RewriteRule ^page\.php$ /target.php?bar=baz [L]
# из http://example.com/page.php?foo=bar
# в http://example.com/target.php?bar=baz
Дописать новый запрос к исходному
RewriteRule ^page\.php$ /target.php?bar=baz [QSA,L]
# из http://example.com/page.php?foo=bar
# в http://example.com/target.php?foo=bar&bar=baz
И кое-что от меня лично (переводчик). Текущий GET-запрос к поддомену превратить в ЧПУ родительского домена:
RewriteCond %{HTTP_HOST} sub\.example\.com [NC]RewriteCond %{QUERY_STRING} ^id=(.+)$
RewriteRule ^.*$ http://example.com/%1? [R=301,L]
# из http://sub.example.com/id=12
n# в http://example.com/12
Здесь %1 - это ссылка на часть условия, не путать с $1 - ссылка в шаблон.
[1oo%, EoF]Понравилась статья? Расскажите о ней друзьям: