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

Сколько памяти Вы видите как 'Зарезервированные Аппаратные средства'? Если его меньше чем 256 МБ, Вы видите память, которая существует в системе, но предварительно выделяется видеокарте.

264
задан 13 February 2015 в 03:26
5 ответов

порядок синтаксиса 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, блог перенаправления запрашивает к специальным serverfault страницам (мы являемся просто настолько особенными). Однако, если вышеупомянутый блок имел дополнительную строку 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 и от Суперпользователя (явный ИЛИ):

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

Служить ServerFault отослало страницы с браузерами Chrome (неявный И):

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 на" в .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 полагает, что это - запуск строка, чтобы быть после "/блог" в 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]) в другом разделе. Поскольку Системные администраторы учатся примером чаще, чем путем чтения страницы справочника, я дам примеры и объясню, что они делают.

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

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

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 однажды эти соответствия. Количества порядка!
C = Цепочка. Продолжите обрабатывать следующий RewriteRule. Если это правило не будет соответствовать, то следующее правило не будет выполняться. Больше на этом позже.
E = Установите переменную окружения. Apache имеет различные переменные окружения, которые могут влиять на поведение веб-сервера.
F = Запрещенный. Возвращает 403-запрещенную ошибку, если это правило соответствует.
G = Уведенный. Возвращает 410 уведенную ошибку, если это правило соответствует.
H = Обработчик. Вынуждает запрос быть обработанным, как будто это был указанный тип MIME.
N = Затем. Вызывает правило запуститься снова и ответный матч. БУДЬТЕ ОСТОРОЖНЫ! Циклы могут закончиться.
NC = Никакой случай. Позволяет jpg соответствовать и jpg и JPG.
NE = Никакой Escape. Предотвращает перезапись специальных символов (.? # и и т.д.) в их эквиваленты шестнадцатеричного кода.
NS = Никакие подзапросы. При использовании server-side-includes это предотвратит соответствия во включенные файлы.
P = Прокси. Вынуждает правило быть обработанным mod_proxy. Прозрачно обеспечьте содержание с других серверов, потому что Ваш веб-сервер выбирает его и резервирует его. Это - опасный флаг, поскольку плохо записанный превратит Ваш веб-сервер в открытый прокси, и Это Плохо.
PT = Проходит. Примите во внимание операторы Alias в соответствии RewriteRule.
QSA = QSAppend. Когда исходная строка содержит запрос (http://example.com/thing?asp=foo), добавляют строку исходного запроса к переписанной строке. Обычно это было бы отброшено. Важный для динамического контента.
R = Перенаправление. Предоставьте перенаправление HTTP указанному URL. Может также предоставить точный код перенаправления [R=303]. Очень похожий на RedirectMatch, который быстрее и должен использоваться, если это возможно.
S = Пропустить. Пропустите это правило.
T = Ввести. Укажите тип пантомимы возвращенного содержания. Очень похожий на 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, второе переписывать-правило выполнится, когда первое сделает, который является, когда предыдущее правило RewriteCond подобрано. Удобный, если регулярные выражения Apache делают Ваш мозговой вред. Однако all-in-one-line метод, на который я указываю в первом разделе, быстрее с точки зрения оптимизации.

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"

224
ответ дан 28 November 2019 в 19:13

Каковы фундаментальный формат и структура правил 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 ErrorLog.

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

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

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

Инструкции Веб-мастера Google явно указывают: "Не обманывайте своих пользователей или представляйте другое содержание поисковым системам, чем Вы отображаетесь пользователям, который обычно упоминается как 'сокрытие'". - стараются не создавать mod_rewrite директивы, которые фильтруют для роботов поисковой системы.

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

Есть ли общие ситуации, где mod_rewrite мог бы походить на правильный инструмент для задания, но не?

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

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

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

39
ответ дан 28 November 2019 в 19:13

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

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

12
ответ дан 28 November 2019 в 19:13

Если это можно сделать с помощью GPO, скорее всего, это можно будет сделать с помощью локальной политики. В качестве администратора машины откройте MMC, добавьте оснастку групповой политики и выберите редактирование локального компьютера. На скольких машинах вам нужно это сделать?

htaccess ).
  • Хуже того, потому что обработка PerDir может почти без разбора запускать цикл ВНУТРЕННЕГО ПОВТОРНОГО ПРЯМОГО, корневые элементы конфигурации должны быть написаны с учетом того, что такая обработка PerDir может вызвать это.
  • Я бы сказал, что из-за этого вам почти нужно разделить сообщества пользователей перезаписи на две категории и рассматривать их как полностью отдельные:

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

    • Пользователи совместно используемой размещенной службы (SHS) .

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

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

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

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

    21
    ответ дан 28 November 2019 в 19:13

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

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

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

    RewriteMap MapName MapType:MapSource
    

    Например:

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

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

    ${examplemap:key}
    

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

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

    Отмена экранирования строк.

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

    Например: я хочу проверить строку "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 будет содержать либо «location», либо «place». Когда вы используете круглые скобки для группировки шаблонов, они также будут захвачены, планируете ли вы использовать результат захвата или нет ...

    15
    ответ дан 28 November 2019 в 19:13

    Теги

    Похожие вопросы