Вопрос: Перенаправление, изменение URL-адресов или перенаправление HTTP на HTTPS в Apache - все, что вы когда-либо хотели знать о правилах Mod_Rewrite, но боялись спросить


Это Канонический вопрос о mod_rewrite от Apache.

Изменение URL-адреса запроса или перенаправление пользователей на другой URL-адрес, чем тот, который они изначально запрашивали, выполняется с помощью mod_rewrite. Сюда входят такие вещи, как:

  • Изменение HTTP на HTTPS (или наоборот)
  • Изменение запроса на страницу, которая больше не существует для новой замены.
  • Изменение формата URL (например, id = 3433 до / id / 3433)
  • Представление другой страницы на основе браузера, основанной на реферере, на основе чего-либо возможного под луной и солнцем.
  • Все, что вы хотите возиться с URL-адресом

Все, что вы когда-либо хотели знать о правилах Mod_Rewrite, но боялись спросить!

Как я могу стать экспертом при написании правил mod_rewrite?

  • Каков основной формат и структура правил mod_rewrite?
  • Какую форму / аромат регулярных выражений мне нужно иметь для полного понимания?
  • Каковы наиболее распространенные ошибки / ловушки при написании правил перезаписи?
  • Что такое хороший метод тестирования и проверки правил mod_rewrite?
  • Есть ли смысл SEO или производительности правил mod_rewrite, о которых я должен знать?
  • Существуют ли распространенные ситуации, когда mod_rewrite может показаться правильным инструментом для работы, но не так ли?
  • Каковы некоторые общие примеры?

Место для проверки ваших правил

Тестер htaccess веб-сайт - отличное место для игры с вашими правилами и тестирования. Он даже показывает вывод отладки, чтобы вы могли видеть, что соответствовало, а что нет.


253
2017-12-20 16:59


Источник


Идея этого вопроса заключается в том, чтобы дать исчерпывающий путь для всех бесконечных вопросов mod_rewrite, которые приводят к тому, что наши более обычные пользователи сходят с ума. Это очень похоже на то, что было сделано с подсети в serverfault.com/questions/49765/how-does-subnetting-work , - Kyle Brandt♦
Кроме того, я не очень хочу, чтобы на этом вопрос, скорее они должны пойти на ответ. Я не хочу, чтобы CW это, потому что я хочу, чтобы плакат получил полный кредит за то, что я надеюсь, это mod_rewrite ответить, чтобы закончить все mod_rewrite вопросы, - Kyle Brandt♦
Извините, я подтвердил этот вопрос. ;-) Я действительно думаю, что он должен появиться на (или рядом) вершине mod-rewrite тегов поиска / фильтров. - Steven Monday
Someone Else (tm) должен обрабатывать обычные прецеденты. Я не знаю их достаточно хорошо, чтобы сделать это справедливо. - sysadmin1138♦
Возможно, этот вопрос должен быть связан с вики-тегом mod-rewrite, чтобы сделать путь еще короче. - beldaz


Ответы:


Порядок синтаксиса mod_rewrite

mod_rewrite имеет некоторые конкретные правила упорядочения, которые влияют на обработку. Прежде чем что-либо будет сделано, RewriteEngine On директива должна быть предоставлена, так как это включает обработку mod_rewrite. Это должно быть до любых других правил перезаписи.

RewriteCond предшествующий RewriteRule делает условие ОДНОГО правила подчиненным условным. Любые последующие RewriteRules будут обрабатываться так, как если бы они не были подвержены условностям.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html

В этом простом случае, если HTTP-реферер отправляется с serverfault.com, перенаправляйте запросы блога на специальные страницы сервера (мы просто такие специальные). Однако, если в вышеуказанном блоке была дополнительная строка RewriteRule:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg         $/blog/$1.sf.jpg

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

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

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

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

Более сложный RewriteRule содержит условные обозначения для обработки. Последнее скобки, (html|jpg) сообщает RewriteRule, что html или jpg, и представить согласованную строку как $ 2 в перезаписываемой строке. Это логически идентично предыдущему блоку с двумя парами RewriteCond / RewriteRule, он просто делает это на двух строках вместо четырех.

Несколько строк RewriteCond неявно ANDed и могут быть явно ORed. Для обработки рефереров как с ServerFault, так и с Super User (явным OR):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)    [OR]
RewriteCond %{HTTP_REFERER}                ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

Чтобы обслуживать серверные страницы с браузерами Chrome (неявные AND):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT}             ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

RewriteBase также определяется по порядку, поскольку он указывает, как следовать RewriteRule директивы обрабатывают их обработку. Это очень полезно в файлах .htaccess. Если он используется, он должен быть первой директивой под «RewriteEngine on» в файле .htaccess. Возьмем следующий пример:

RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

Это говорит mod_rewrite, что этот конкретный URL-адрес, который он сейчас обрабатывает, был получен путем http://example.com/blog/ вместо физического пути к каталогу (/ home / $ Username / public_html / blog) и соответствующим образом обрабатывать его. Из-за этого RewriteRule считает, что начало строки после «/ blog» в URL-адресе. Вот то же самое написано двумя разными способами. Один с RewriteBase, другой без:

RewriteEngine On

##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER}                                   ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg)     $1.sf.$2

##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

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


Синтаксис соответствия RewriteRule

RewriteRule сам имеет сложный синтаксис для сопоставления строк. Я покрою флаги (например, [PT]) в другом разделе. Поскольку Sysadmins учатся на примере чаще, чем путем чтения человек-страница Я приведу примеры и объясню, что они делают.

RewriteRule ^/blog/(.*)$    /newblog/$1

.* Конструкция соответствует любому одиночному символу (.) ноль или более раз (*). Приложив его в скобках, он сообщает, что он должен содержать строку, которая была сопоставлена ​​как переменная $ 1.

RewriteRule ^/blog/.*/(.*)$  /newblog/$1

В этом случае первый. * Не был заключен в parens, поэтому не предоставляется перезаписываемая строка. Это правило удаляет уровень каталогов на новом блоге. (/blog/2009/sample.html становится /newblog/sample.html).

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$2

В этом случае первое выражение в скобках устанавливает соответствующую группу. Это становится $ 1, что не требуется и поэтому не используется в перезаписываемой строке.

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$1/$2

В этом случае мы используем $ 1 в перезаписываемой строке.

RewriteRule ^/blog/(20[0-9][0-9])/(.*)$   /newblog/$1/$2

Это правило использует специальный синтаксис скобок, который задает символ ассортимент, [0-9] соответствует цифрам от 0 до 9. Это конкретное правило будет обрабатывать годы с 2000 по 2099 год.

RewriteRule ^/blog/(20[0-9]{2})/(.*)$  /newblog/$1/$2

Это делает то же, что и предыдущее правило, но часть {2} сообщает ему, чтобы он совпадал с предыдущим символом (выражение в скобках в этом случае) два раза.

RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html   /newblog/$1/$2.shtml

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

RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html  /newblog/$1/$2.shtml

Это имена файлов ловушек с тире в них. Однако, поскольку - является особым символом в выражениях скобок, он должен быть первый символ в выражении.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Эта версия останавливает любое имя файла с помощью букв, цифр или - символ в имени файла. Так вы указываете несколько наборов символов в выражении скобки.


Флаги RewriteRule

Флаги по правилам перезаписи содержат множество специальных значений и единиц,

RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html  /newblog/$1/$2.shtml  [L]

Флаг - это [L] в конце вышеприведенного выражения. Можно использовать несколько флагов, разделенных запятой. Связанная документация описывает каждый, но здесь они все равно:

L = Последнее. Прекратите обработку RewriteRules после этого. Количество заказов!
С = Цепочка. Продолжайте обработку следующего RewriteRule. Если это правило не соответствует, то следующее правило не будет выполнено. Подробнее об этом позже.
Е = Установить переменную окружения. Apache имеет различные переменные среды, которые могут влиять на поведение веб-сервера.
F = Запрещено. Возвращает ошибку 403-Forbidden, если это правило соответствует.
г = Ушел. Возвращает ошибку 410-Gone, если это правило соответствует.
ЧАС = Обработчик. Заставляет запрос обрабатываться так, как если бы он был указан MIME-типом.
N = Далее. Заставляет правило начинать заново и повторно сопоставлять. БЫТЬ ОСТОРОЖЕН! В результате могут возникать петли.
Северная Каролина = Нет случая. Позволяет jpg для соответствия JPG и JPG.
Небраска = Нет побега. Предотвращает переписывание специальных символов (.? # И т. Д.) В их эквиваленты шестнадцатеричного кода.
NS = Без подзапросов. Если вы используете серверные компоненты, это предотвратит совпадение с включенными файлами.
п = Прокси. Заставляет правило обрабатываться mod_proxy. Прозрачно предоставлять контент с других серверов, потому что ваш веб-сервер извлекает его и повторно обслуживает. Это опасный флаг, так как плохо написанный превратит ваш веб-сервер в открытый прокси, и это плохо.
PT = Пропустить. Учитывайте утверждения Alias ​​в RewriteRule.
QSA = QSAppend. Когда исходная строка содержит запрос (http://example.com/thing?asp=foo) добавьте исходную строку запроса в перезаписанную строку. Обычно это было бы отброшено. Важно для динамического содержимого.
р = Перенаправление. Предоставьте HTTP-переадресацию указанному URL-адресу. Также может предоставлять точный код перенаправления [R = 303]. Очень похоже на RedirectMatch, который быстрее и должен использоваться, когда это возможно.
S = Пропустить. Пропустите это правило.
T = Тип. Укажите mime-тип возвращаемого содержимого. Очень похоже на AddType директивы.

Вы знаете, как я сказал, что RewriteCond применяется к одному и только одному правилу? Ну, вы можете обойти это, цепляясь.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html     [C]
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

Поскольку первый RewriteRule имеет флаг Chain, второе правило rewrite будет выполняться, когда выполняется первое, что соответствует правилу предыдущего RewriteCond. Удобно, если регулярные выражения Apache заставляют ваш мозг болеть. Однако метод «все в одной строке», который я указываю в первом разделе, быстрее с точки зрения оптимизации.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Это можно упростить с помощью флагов:

RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html   /newblog/$1/$2.shtml   [NC]

Кроме того, некоторые флаги применяются также к RewriteCond. Примечательно, что NoCase.

RewriteCond %{HTTP_REFERER}        ^https?://serverfault\.com(/|$)     [NC]

Будет соответствовать "ServerFault.com"


216
2017-12-20 17:44



Отлично сработано. [Наполнителя] - EEAA♦
Очень хорошо mod_rewrite и регулярное праймер. +1. - Steven Monday
Иногда полезно знать, что RewriteCond фактически обрабатывается после  RewriteRule соответствует. Возможно, вы захотите сказать «подробнее об этом позже» около вершины, где вы говорите: «RewriteCond, предшествующий RewriteRule, делает одно правило подчиненным условным». Вы можете упомянуть, что регулярные выражения являются регулярными выражениями, совместимыми с Perl. Кроме того, у вас есть посторонний апостроф в «... RewriteRule считает, что это начало строки ...» - Dennis Williamson
RewriteRule ^/blog/.*/(.*)$ /newblog/$1 не соответствует первый Компонент каталога - перезаписываются по умолчанию. /.*/(.*) соответствует как / 1 / (2) /, так и 1/2/3/4/5 / (6) /, поэтому вам нужно / [^ /] * /, чтобы соответствовать только первому пути компонент. - adaptr
@ sysadmin1138, я думаю, что этот ответ хорош, но может быть лучше, если вы подробнее рассмотрите флаги E, N, NS, P, PT и S с примерами, поскольку эти флаги не очевидны, как они работают и т. д. - Pacerier


Каков основной формат и   структура правил mod_rewrite?

Я отложил бы отличный ответ sysadmin1138 по этим вопросам.

Какая форма / аромат регулярных   мне нужно иметь твердые   понять?

В дополнение к порядку синтаксиса, синтаксическому согласованию / регулярным выражениям и флагам RewriteRule, описанным sysadmin1138, я считаю, что следует отметить, что mod_rewrite предоставляет переменные среды Apache на основе заголовков HTTP-запросов и конфигурации Apache.

Я бы посоветовал Учебное пособие по отладке mod_rewrite от AskApache для полного списка переменных, которые могут быть доступны для mod_rewrite.

Каковы наиболее распространенные   ошибки / ловушки при написании перезаписи   правила?

Большинство проблем с RewriteRule проистекают из непонимания синтаксиса PCRE / неспособности должным образом избежать специальных символов или отсутствия понимания содержимого переменных (переменных), используемых для сопоставления.

Типичные проблемы и рекомендации по устранению неполадок:

  • 500 - внутренняя ошибка сервера - Удаление элементов управления каретки Windows в файлах конфигурации, если они есть, убедитесь, что mod_rewrite включен (директивы об обращении в IfModule условно, чтобы избежать этого сценария), проверить директивный синтаксис, прокомментировать директивы, пока не будет выявлена ​​проблема
  • Переадресация цикла - Использовать RewriteLog и RewriteLogLevel, прокомментировать директивы, пока не будет выявлена ​​проблема

Что такое хороший метод тестирования и   проверка правил mod_rewrite?

Во-первых, посмотрите на содержимое переменных (-ов) среды, которые вы планируете сопоставить, - если у вас установлен PHP, это так же просто, как добавление следующего блока в ваше приложение:

<?php
  var_dump($_SERVER);
?>

... затем напишите свои правила (желательно для тестирования на сервере разработки) и обратите внимание на любое несогласованное соответствие или активность в вашем Apache Журнал ошибок файл.

Для более сложных правил используйте mod_rewrite's RewriteLog директива о регистрации активности в файле и RewriteLogLevel 3

Есть ли SEO или производительность?   последствия правил mod_rewrite I   должен знать?

AllowOverride all влияет на производительность сервера, поскольку Apache должен проверить .htaccess файлы и синтаксические разборки с каждым запросом - если возможно, сохраните все директивы в конфигурации VirtualHost для вашего сайта или включите .htaccess переопределяет только каталоги, которые в них нуждаются.

Google-х Руководства для веб-мастеров явным образом заявляю: «Не обманывайте своих пользователей или не представляйте разные материалы в поисковых системах, чем вы показываете пользователям, что обычно называют« клоакинг ». - Не создавайте директивы mod_rewrite, которые фильтруют для роботов поисковых систем.

Поисковые роботы предпочитают сопоставление 1: 1: отображение URI (это основа для ранжирования ссылок на контент). Если вы используете mod_rewrite для создания временных перенаправлений или используете один контент в нескольких URI, подумайте о том, чтобы указать канонический URI в ваших HTML-документах.

Существуют ли общие ситуации, когда   mod_rewrite может показаться правильным   инструмент для работы, но не так ли?

Это огромная (и, возможно, спорная) тема сама по себе - лучше (ИМХО), чтобы обращаться к использованию в каждом конкретном случае и позволять акимам определять, соответствуют ли предлагаемые резолюции их потребностям.

Каковы некоторые общие примеры?

Трюки и советы AskApache's mod_rewrite охватывает практически каждый распространенный случай использования, который появляется регулярно, однако «правильное» решение для данного пользователя может зависеть от сложности конфигурации пользователя и существующих директив (именно поэтому в целом это хорошая идея, чтобы увидеть, какие Другие директивы, которые пользователь имеет в наличии, когда возникает вопрос mod_rewrite).


38
2017-12-21 01:00



Спасибо за ссылку AskApache. Это то, что я искал! - sica07
Клоун AskApache официально не поддерживается ASF. Многое из того, что он говорит, что это спорно или просто неправильно. - adaptr
@adaptr Пожалуйста, поделитесь превосходными ресурсами, о которых вы, очевидно, знаете. - danlefree
«Обычные ситуации, когда mod_rewrite может показаться правильным инструментом для работы, но не так ли?» - просто перенаправления, где mod_rewrite еще не используется. Использовать mod_alias Redirect или RedirectMatch вместо. См. Также документы Apache: Когда не использовать mod_rewrite - MrWhite


Как и многие администраторы / разработчики, я много лет борюсь с сложностями правил перезаписи и недовольны существующей документацией Apache, поэтому я решил как личный проект, чтобы понять, как mod_rewrite фактически работает и взаимодействует с остальной частью ядра Apache, поэтому за последние несколько месяцев я тестировал тестовые примеры с strace + сверление в исходный код, чтобы получить дескриптор всего этого.

Вот некоторые ключевые комментарии, которые необходимо переписать разработчикам правил:

  • Некоторые аспекты перезаписи являются общими для конфигурации сервера, виртуального хоста, каталога, обработки .htaccess Однако
  • Некоторая обработка сильно отличается для корневой конфигурации (конфигурации сервера, виртуального хоста и каталога) в отличие от PerDir (.htaccess) обработка.
  • Хуже того, что обработка PerDir может почти без разбора вызвать цикл INTERNAL REDIRECT, элементы корневой конфигурации должны быть осведомлены о том, что такая обработка PerDir может вызвать это.

Я хотел бы сказать, что из-за этого вам почти необходимо разделить сообщества пользователей перезаписи на две категории и рассматривать их как совершенно отдельные:

  • Те, у кого есть root-доступ к конфигурации Apache, Обычно это админ / разработчик с выделенным сервером приложений / VM, и сообщение здесь довольно просто: не используйте .htaccess если это вообще возможно; сделайте все на своем сервере или конфигурацию vhost. Отладка разумна, так как разработчик может устанавливать отладку и имеет доступ к файлам rewrite.log.

  • Пользователи совместно используемой услуги (SHS),

    • Такие пользователи иметь использовать .htaccess / Perdir, поскольку альтернативы нет.
    • Хуже того, уровень навыков таких пользователей (насколько используется релейно-логическая логика mod_rewrite с регулярным выражением), как правило, значительно меньше, чем у опытных администраторов.
    • Apache и хостинг-провайдеры не поддерживают поддержку отладки / диагностики. Единственной диагностической информацией является успешное перенаправление, перенаправление на неправильный URI. или код статуса 404/500. Это оставляет их смущенными и беспомощными.
    • Apache крайне слаб, объясняя, как переписывание работает для этого варианта использования. Например, это не дает четкого объяснения того, что такое PerDir .htaccessфайл выбран и почему. Это не объясняет тонкости езды на PerDir и как этого избежать.

Возможно, есть третье сообщество: администратор и вспомогательный персонал в провайдерах SHS, у которых в лагере есть нога, и они должны пострадать от последствий вышеуказанного.

Я написал несколько статей в блоге в стиле статьи (например, Подробнее об использовании правил перезаписи в файлах .htaccess), который охватывает множество подробных пунктов, которые я не буду повторять здесь, чтобы сохранить этот пост коротким. У меня есть собственный общий сервис, а также поддержка некоторых специализированных проектов VMO FLOSS. Я начал использовать стандартную виртуальную машину LAMP в качестве тестового автомобиля для моей учетной записи SHS, но в конце концов мне было лучше сделать правильную зеркальную VM (описанную Вот).

Однако с точки зрения того, как административное сообщество должно поддерживать .htaccess пользователей, я чувствую, что нам нужно разработать и предложить:

  • Согласованное описание того, как система перезаписи фактически работает в PerDir-обработке
  • Набор руководящих принципов / рекомендаций по написанию .htaccess переписать правила
  • Простой веб-анализатор перезаписи сценариев похож на W3C html-синтаксический анализатор, но с помощью которого пользователи могут вводить тестовые URI или тестовые векторы того же самого и получать немедленный журнал логического потока rewrite /
  • Советы по созданию встроенной диагностики из ваших правил (например,

    • использование [E=VAR:EXPR] используя тот факт, что EXPR будет расширять обратные ссылки ($ N или% N), чтобы сделать их доступными в качестве диагностики для целевого скрипта.
    • Если вы местным образом заказываете свои правила перезаписи с использованием флагов [OR], [C], [SKIP] и [L], чтобы вся схема перезаписи работала без необходимо использовать внутреннее перенаправление, тогда вы можете добавить следующее как правило 1, чтобы избежать всех проблем с циклом:

      RewriteCond %{ENV:REDIRECT_STATUS} !=""
      RewriteRule .  -  [L]
      

20
2018-01-14 16:50



Это хорошо документировано. Почему вы говорите, что документация не объясняет это? - adaptr
Все, что вам нужно сделать, это подписаться на .htaccess темы, и вы увидите. Большинство новичков безнадежно путают - большинство из них имеют свой первый опыт работы с LAMP и mod_rewrite на общей службе и, следовательно, не имеют корневого доступа к конфигурациям system / vhost и должны использовать per dir-обработку через .htaccessфайлы. Существуют важные отличия, которые новичок должен «истекать кровью». Я бы считал себя силовым пользователем и все еще обнаруживаю тонкости. Как я сказал, мне пришлось использовать strace и сканирование исходного кода для разработки некоторых аспектов. Не нужно. :-( - TerryE
Я абсолютно согласен. «Мы должны разделить сообщества пользователей перезаписи на две категории и рассматривать их как совершенно отдельные». Некоторые пользователи используют общий хостинг и необходимость полагаться на .htaccess, который ужасно хрупкий, сложный и запутанный, даже для экспертов. У меня все еще есть проблемы. - Ryan


Использование rewritemap

Есть много вещей, которые вы можете сделать с rewritemaps. Rewritemaps объявляются с использованием директивы Rewritemap и затем могут использоваться как в оценках RewritCond, так и в RewriteRule Subsitutions.

Общий синтаксис RewriteMap:

RewriteMap MapName MapType:MapSource

Например:

RewriteMap examplemap txt:/path/to/file/map.txt

Затем вы можете использовать mapname для таких конструкций:

${examplemap:key}

Карта содержит пары ключ / значение. Если ключ найден, значение будет заменено. Простые карты - это просто текстовые файлы, но вы можете использовать хеш-карты и даже SQL-запросы. Более подробная информация содержится в документах:

http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap

Unescaping string.

Есть четыре внутренних карты, которые вы можете использовать для выполнения некоторых манипуляций. Особенно бесполезные строки могут пригодиться.

Например: я хочу проверить строку «café» в строке запроса. Тем не менее, браузер избежит этого, прежде чем отправлять его на мой сервер, поэтому мне нужно будет выяснить, что версия с экранированной URL-адресом предназначена для каждой строки, которую я хочу сопоставить, или я могу просто отменить ее ...

RewriteMap unescape int:unescape

RewriteCond %{QUERY_STRING}  (location|place)=(.*)
RewriteCond ${unescape:%2}   café
RewriteRule ^/find/$         /find/1234? [L,R]

Обратите внимание, как я использую один RewriteCond, чтобы просто захватить аргумент для параметра строки запроса, а затем использовать карту во втором rewriteCond для ее отмены. Затем это сравнивается. Также обратите внимание на то, как мне нужно% 2 в качестве ключа в rewritemap, поскольку% 1 будет содержать «местоположение» или «место». Когда вы используете круглые скобки для группировки паттернов, они также будут захвачены, если вы планируете использовать результат захвата или нет ...


15
2018-04-06 11:57



Последнее предложение не совсем верно. mod_rewrite regexp поддерживает не захватывающие группы, такие как (?:location|place) и в этом примере будет только один захват. - TerryE


Каковы наиболее распространенные   ошибки / ловушки при написании перезаписи   правила?

Очень простая ошибка - это когда вы переписываете URL-адреса, которые изменяют видимый путь, например. из /base/1234/index.html в /base/script.php?id=1234, Любые изображения или CSS с относительными путями к местоположению сценария не будут найдены клиентом. Ряд вариантов решения этой проблемы можно найти на это faq,


12
2018-01-01 04:02



Спасибо за ссылку. В частности, при работе с другими членами команды, которые не знакомы с переписыванием, я считаю, <base> тег, который будет наиболее легко следовать и по-прежнему включать относительные пути. - kontur