Это канонический вопрос о mod_rewrite в Apache.
Изменение URL-адреса запроса или перенаправление пользователей на URL, отличный от того, который они первоначально запрашивали, выполняется с помощью mod_rewrite. Это включает в себя такие вещи, как:
- Изменение HTTP на HTTPS (или наоборот)
- Изменение запроса на страницу, которая больше не существует, на новую замену.
- Изменение формата URL (например,? Id = 3433 в / id / 3433)
- Представление другой страницы на основе браузера, на основе реферера, на основе всего, что возможно под луной и солнцем.
- Все, что вы хотите возиться с URL
Все, что вы когда-либо хотели знать о правилах Mod_Rewrite, но боялись спросить!
Как я могу стать экспертом в написании правил mod_rewrite?
- Каков основной формат и структура правил mod_rewrite?
- Какую форму / вид регулярных выражений мне нужно иметь твердое представление?
- Каковы наиболее распространенные ошибки / подводные камни при написании правил переписывания?
- Что такое хороший метод для тестирования и проверки правил mod_rewrite?
- Есть ли какие-то последствия для правил mod_rewrite для SEO или производительности, о которых мне следует знать?
- Есть ли общие ситуации, когда mod_rewrite может показаться подходящим инструментом для работы, но это не так?
- Каковы некоторые общие примеры?
Место для проверки ваших правил
Htaccess тестер веб - сайт является отличным местом , чтобы играть с вашими правилами и протестировать их. Он даже показывает выходные данные отладки, чтобы вы могли видеть, что соответствует, а что нет.
apache-2.2
mod-rewrite
redirect
redirection
301-redirect
Кайл Брандт
источник
источник
mod-rewrite
поисков / фильтров тегов.Ответы:
порядок синтаксиса mod_rewrite
У mod_rewrite есть некоторые определенные правила упорядочения, которые влияют на обработку. Прежде чем что-либо сделать,
RewriteEngine On
необходимо дать директиву, поскольку это включает обработку mod_rewrite. Это должно быть перед любыми другими директивами перезаписи.RewriteCond
предшествующееRewriteRule
делает это ЕДИНОЕ правило подчиненным условию. Любые последующие RewriteRules будут обрабатываться так, как если бы они не подлежали условным условиям.В этом простом случае, если HTTP-реферер принадлежит serverfault.com, перенаправляйте запросы блога на специальные страницы serverfault (мы просто такие особенные). Однако, если вышеупомянутый блок имел дополнительную строку RewriteRule:
Все файлы .jpg попадают на специальные страницы с ошибками сервера, а не только с ссылками, указывающими, что они пришли отсюда. Это явно не цель написания этих правил. Это можно сделать с помощью нескольких правил RewriteCond:
Но, вероятно, это должно быть сделано с более сложным синтаксисом замены.
Более сложный RewriteRule содержит условия для обработки. Последняя скобка
(html|jpg)
указывает RewriteRule на совпадение для любогоhtml
или илиjpg
и для представления сопоставленной строки как $ 2 в переписанной строке. Это логически идентично предыдущему блоку, с двумя парами RewriteCond / RewriteRule, он просто делает это в две строки вместо четырех.Несколько строк RewriteCond неявно объединяются и могут быть явно ORed. Для обработки ссылок от ServerFault и Super User (явное ИЛИ):
Для обслуживания страниц, на которые ссылается ServerFault, браузерами Chrome (неявное И):
RewriteBase
также зависит от порядка, поскольку определяет, как следующиеRewriteRule
директивы обрабатывают их обработку. Это очень полезно в файлах .htaccess. Если используется, это должна быть первая директива в разделе «RewriteEngine on» в файле .htaccess. Возьмите этот пример:Это говорит mod_rewrite, что этот конкретный URL, который он обрабатывает в настоящее время, был получен посредством http://example.com/blog/ вместо физического пути к каталогу (/ home / $ Username / public_html / blog) и обрабатывается соответствующим образом. Из-за этого
RewriteRule
он считает, что это начало строки после "/ blog" в URL. Здесь одно и то же написано двумя разными способами. Один с RewriteBase, другой без:Как видите,
RewriteBase
позволяет переписать правила, чтобы использовать путь веб- сайта к контенту, а не веб- сервер , что может сделать их более понятными для тех, кто редактирует такие файлы. Кроме того, они могут сделать директивы короче, что имеет эстетическую привлекательность.RewriteRule, соответствующий синтаксису
Сам RewriteRule имеет сложный синтаксис для сопоставления строк. Я покрою флаги (такие как [PT]) в другом разделе. Поскольку системные администраторы учатся на примере чаще, чем читая справочную страницу, я приведу примеры и объясню, что они делают.
.*
Конструкция соответствует любому одному символу (.
) ноль или более раз (*
). Заключив его в круглые скобки, вы должны указать строку, которая соответствует переменной $ 1.В этом случае первый. * НЕ был заключен в скобки, поэтому не передается переписанной строке. Это правило удаляет уровень каталога на новом блог-сайте. (/blog/2009/sample.html становится /newblog/sample.html).
В этом случае первое выражение в скобках устанавливает соответствующую группу. Это становится $ 1, который не нужен и, следовательно, не используется в переписанной строке.
В этом случае мы используем $ 1 в переписанной строке.
Это правило использует специальный синтаксис скобок, который определяет диапазон символов . [0-9] соответствует цифрам от 0 до 9. Это конкретное правило будет относиться к годам с 2000 по 2099 год.
Это делает то же самое, что и предыдущее правило, но часть {2} сообщает ему о совпадении с предыдущим символом (в данном случае это выражение в скобках) два раза.
Этот регистр будет соответствовать любой строчной букве во втором совпадающем выражении и делать это для максимально возможного количества символов.
\.
Конструкция говорит это , чтобы рассматривать период как фактический период, а не особый характер это в предыдущих примерах. Это сломается, если имя файла содержит тире.Это ловит имена файлов с тире в них. Однако, как
-
специальный символ в выражениях в скобках, он должен быть первым символом в выражении.Эта версия захватывает любое имя файла буквами, цифрами или
-
символом в имени файла. Вот как вы указываете несколько наборов символов в выражении в скобках.RewriteRule flags
Флаги в правилах перезаписи имеют множество специальных значений и вариантов использования .
Флаг находится
[L]
в конце вышеприведенного выражения. Можно использовать несколько флагов, разделенных запятой. Связанная документация описывает каждого, но вот они в любом случае:L = последний. Прекратите обработку RewriteRules, как только этот совпадет. Заказ имеет значение!
C = цепь Продолжить обработку следующего RewriteRule. Если это правило не соответствует, то следующее правило не будет выполнено. Подробнее об этом позже.
E = установить переменную среды. Apache имеет различные переменные среды, которые могут влиять на поведение веб-сервера.
F = запрещено. Возвращает ошибку 403-Forbidden, если это правило соответствует.
G = Ушел. Возвращает ошибку 410-Gone, если это правило соответствует.
H = Обработчик. Принудительно обрабатывает запрос, как если бы он был указанным MIME-типом.
N = Далее. Заставляет правило начать все заново и заново сопоставить. БЫТЬ ОСТОРОЖЕН! Петли могут привести.
NC = Нет дела. Позволяет
jpg
соответствовать как JPG, так и JPG.NE = нет выхода. Предотвращает перезапись специальных символов (.? # & Etc) в их эквиваленты в шестнадцатеричном коде.
NS = Нет подзапросов. Если вы используете серверные включения, это предотвратит совпадение с включенными файлами.
P = прокси. Принудительно обрабатывает правило с помощью mod_proxy. Прозрачно предоставлять контент с других серверов, потому что ваш веб-сервер получает его и повторно обслуживает. Это опасный флаг, так как плохо написанный превратит ваш веб-сервер в открытый прокси, и это плохо.
PT = Pass Through. Примите во внимание операторы Alias в соответствии RewriteRule.
QSA = QSAppend. Если исходная строка содержит запрос ( http://example.com/thing?asp=foo) добавить исходную строку запроса к переписанной строке. Обычно это будет отброшено. Важно для динамического контента.
R = Перенаправление. Предоставьте HTTP-перенаправление на указанный URL-адрес. Может также предоставить точный код перенаправления [R = 303]. Очень похоже на то
RedirectMatch
, что быстрее и должно использоваться, когда это возможно.S = Пропустить. Пропустите это правило.
T = Тип. Укажите mime-тип возвращаемого содержимого. Очень похоже на
AddType
директиву.Вы знаете, как я сказал, что это
RewriteCond
относится к одному и только одному правилу? Ну, вы можете обойти это, цепочки.Поскольку первый RewriteRule имеет флаг Chain, второе правило перезаписи будет выполнено, когда первое выполнит, то есть, когда будет найдено предыдущее правило RewriteCond. Удобно, если регулярные выражения Apache причиняют боль вашему мозгу. Однако метод «все в одной строке», на который я указываю в первом разделе, быстрее с точки зрения оптимизации.
Это можно упростить с помощью флагов:
Кроме того, некоторые флаги также применяются к RewriteCond. В частности, NoCase.
Будет соответствовать "ServerFault.com"
источник
mod_rewrite
и регулярный учебник для начинающих. +1.RewriteCond
на самом деле обрабатывается послеRewriteRule
подобран. Возможно, вы захотите сказать «подробнее об этом позже» в верхней части, где вы говорите: «RewriteCond, предшествующий RewriteRule, делает это ЕДИНОЕ правило подчиненным условию». Вы можете упомянуть, что регулярные выражения являются Perl-совместимыми регулярными выражениями. Также у вас есть посторонний апостроф в «... RewriteRule считает, что это начало строки ...»RewriteRule ^/blog/.*/(.*)$ /newblog/$1
не соответствует первому компоненту каталога - по умолчанию rewriterules являются жадными. /.*/(.*) соответствует обоим / 1 / (2) / и / 1/2/3/4/5 / (6) /, поэтому вам необходимо / [^ /] * / соответствовать только ПЕРВОМУ пути составная часть.Я отложу до превосходного ответа sysadmin1138 по этим вопросам.
В дополнение к порядку синтаксиса, сопоставлению синтаксиса / регулярным выражениям и флагам RewriteRule, описанным sysadmin1138, я считаю, что стоит упомянуть, что mod_rewrite предоставляет переменные среды Apache на основе заголовков HTTP-запросов и конфигурации Apache.
Я бы порекомендовал AskApache mod_rewrite Учебник по отладке для полного списка переменных, которые могут быть доступны для mod_rewrite.
Большинство проблем с RewriteRule проистекают из-за неправильного понимания синтаксиса PCRE / неспособности должным образом экранировать специальные символы или отсутствия понимания содержимого переменных, используемых для сопоставления.
Типичные проблемы и рекомендуемые способы устранения неполадок:
IfModule
условно, чтобы избежать этого сценария), проверьте синтаксис директив, закомментируйте директивы, пока проблема не будет выявленаВо-первых, посмотрите на содержимое переменных среды, с которыми вы планируете сравнивать - если у вас установлен PHP, это так же просто, как добавить следующий блок в ваше приложение:
... затем напишите свои правила (желательно для тестирования на сервере разработки) и запишите все несоответствия или действия в файле Apache ErrorLog .
Для более сложных правил используйте
RewriteLog
директиву mod_rewrite, чтобы записать активность в файл и установитьRewriteLogLevel 3
AllowOverride all
влияет на производительность сервера, так как Apache должен проверять.htaccess
файлы и разбирать директивы с каждым запросом - если возможно, сохраняйте все директивы в конфигурации VirtualHost для своего сайта или разрешайте.htaccess
переопределения только для каталогов, которые в них нуждаются.В Руководстве Google для веб-мастеров прямо говорится: «Не обманывайте своих пользователей и не представляйте поисковикам другой контент, отличный от показанного пользователям, что обычно называют« маскировкой ».» - избегайте создания директив mod_rewrite, которые фильтруют роботов поисковых систем.
Роботы поисковых систем предпочитают отображение контента 1: 1: сопоставление URI (это основа для ранжирования ссылок на контент) - если вы используете mod_rewrite для создания временных перенаправлений или вы обслуживаете один и тот же контент под несколькими URI, рассмотрите возможность указания канонического URI в ваши HTML документы.
Это огромная (и потенциально спорная) тема сама по себе - лучше (ИМХО) решать вопросы использования в каждом конкретном случае и позволять спрашивающим определять, соответствуют ли предложенные резолюции их потребностям.
Полезные советы и советы ModArewache от AskApache охватывают практически все распространенные варианты использования, которые регулярно появляются, однако «правильное» решение для данного пользователя может зависеть от сложности конфигурации пользователя и существующих директив (именно поэтому обычно это хорошая идея, чтобы увидеть, какие другие директивы имеет пользователь при возникновении вопроса mod_rewrite).
источник
Redirect
илиRedirectMatch
вместо этого. См. Также документы Apache: когда не следует использовать mod_rewriteКак и многие администраторы / разработчики, я годами боролся со сложностями правил переписывания и недоволен существующей документацией Apache, поэтому я решил, как личный проект, разобраться в том, как на
mod_rewrite
самом деле работает и взаимодействует с остальной частью Apache. ядро, так что в последние несколько месяцев я тестировал кейсы сstrace
+ детализацией в исходном коде, чтобы справиться со всем этим.Вот некоторые ключевые комментарии, которые необходимо учитывать разработчикам правил переписывания:
.htaccess
).Я хотел бы сказать, что из-за этого вам почти нужно разделить сообщества переписанных пользователей на две категории и рассматривать их как совершенно отдельные:
Те, у кого есть root-доступ к конфигурации Apache . Обычно это администратор / разработчик с выделенным сервером / виртуальной машиной приложения, и сообщение здесь довольно простое: избегайте использования
.htaccess
файлов, если это возможно; сделать все на вашем сервере или vhost config. Отладка достаточно проста, так как разработчик может установить отладку и имеет доступ к файлам rewrite.log.Пользователи общего хостинга (SHS) .
.htaccess
обработку / Perdir, поскольку альтернативы нет..htaccess
файл PerDir выбран и почему. Это не объясняет тонкости езды на велосипеде PerDir и как избежать этого.Возможно, существует третье сообщество: администратор и вспомогательный персонал поставщиков услуг SHS, которые в обоих лагерях оказываются в одной ноге и вынуждены страдать от последствий вышеуказанного.
Я написал пару постов в стиле статей (например, Подробнее об использовании правил перезаписи в файлах .htaccess ), которые охватывают множество подробных моментов, которые я не буду повторять здесь, чтобы этот пост был коротким. У меня есть собственный сервис, а также поддержка некоторых выделенных проектов и проектов VM FLOSS. Я начал использовать стандартную виртуальную машину LAMP в качестве тестовой машины для своей учетной записи SHS, но в итоге я обнаружил, что лучше создать правильную зеркальную виртуальную машину (описано здесь ).
Однако, с точки зрения того, как сообщество администраторов должно поддерживать
.htaccess
пользователей, я чувствую, что нам нужно развиваться и предлагать:.htaccess
правила перезаписиСоветы о том, как получить встроенную диагностику из ваших правил (например,
[E=VAR:EXPR]
использование факта,EXPR
который расширит обратные ссылки ($ N или% N), чтобы сделать их доступными в качестве диагностики для целевого сценария.Если вы тематически упорядочите свои правила перезаписи, используя флаги [OR], [C], [SKIP] и [L], чтобы вся схема перезаписи работала без использования внутреннего перенаправления, то вы можете добавить следующее как правило 1, чтобы избежать все циклы хлопот:
источник
.htaccess
темы, и вы увидите. Большинство новичков безнадежно запутались - большинство из них имеют свой первый опыт работы со службой LAMP и mod_rewrite в общей службе и поэтому не имеют корневого доступа к системным / vhost-конфигурациям, и им приходится использовать обработку dir через.htaccess
файлы. Существуют важные отличия, которые новичок должен «пролить». Я бы считал себя опытным пользователем и все еще открываю для себя тонкости. Как я уже сказал, мне пришлось использовать сканирование с помощью strace и исходного кода для проработки некоторых аспектов. В этом нет необходимости. :-(.htaccess
, что очень хрупкий, сложном и запутанном, даже для специалистов. У меня все еще проблемы.Использование rewritemap
Есть много вещей, которые вы можете сделать с переписанными картами. Rewritemaps объявляются с использованием директивы Rewritemap и могут затем использоваться как в оценках RewritCond, так и в подразделах RewriteRule.
Общий синтаксис для RewriteMap:
Например:
Затем вы можете использовать mapname для таких конструкций:
Карта содержит пары ключ / значение. Если ключ найден, значение заменяется. Простые карты - это просто текстовые файлы, но вы можете использовать хэш-карты и даже запросы SQL. Более подробная информация в документах:
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap
Unescaping строки.
Есть четыре внутренних карты, которые вы можете использовать для некоторых манипуляций. Особенно беспрепятственные струны могут пригодиться.
Например: я хочу проверить строку "café" в строке запроса. Тем не менее, браузер избежит этого перед отправкой на мой сервер, поэтому мне нужно будет либо выяснить, что такое экранированная версия URL для каждой строки, которую я хочу сопоставить, либо я могу просто удалить ее ...
Обратите внимание, как я использую один RewriteCond для захвата аргумента в параметре строки запроса, а затем использую карту во втором rewriteCond для его удаления. Это тогда сравнивается. Также обратите внимание, что мне нужно использовать% 2 в качестве ключа в карте перезаписи, так как% 1 будет содержать «location» или «place». Когда вы используете скобки для группировки шаблонов, они также будут захвачены, независимо от того, планируете ли вы использовать результат захвата или нет ...
источник
mod_rewrite
регулярных выражений поддерживает группы без захвата, например,(?:location|place)
и в этом примере будет только один захват.Очень простой подводный камень - это когда вы переписываете URL, которые изменяют видимый путь, например, с
/base/1234/index.html
на/base/script.php?id=1234
. Любые изображения или CSS с относительными путями к местоположению скрипта не будут найдены клиентом. Несколько вариантов решения этой проблемы можно найти в этом FAQ .источник
<base>
тега является наиболее простым для отслеживания и в то же время включает относительные пути.