Я пытаюсь смоделировать структуру постоянных ссылок предыдущей версии моего сайта, используя правила Redirect и RedirectMatch в моем файле .htaccess.
У меня есть разные правила, которые я бы применил к разным путям с моего старого сайта. У некоторых каталогов нет аналогов, и я хочу, чтобы они перенаправлялись в одно место. Некоторые каталоги содержат много элементов (тысячи) в разных местах, и я хочу, чтобы они разумно перенаправлялись в правильные новые места на новом сайте.
Кажется, я мог бы защитить и сгруппировать связанные элементы с помощью базового теста регулярного выражения на <If>, чтобы предотвратить тестирование всех содержащихся сгруппированных перенаправлений, если они никогда не будут совпадать. В этом методе результирующая конфигурация выглядит логичной и последовательной и может быть легко сгенерирована автоматически:
<If "%{REQUEST_URI} =~ m#^/categories/software/.*#">
# These rules aren't considered if the request wasn't for a subpath of categories/software.
<If "%{REQUEST_URI} =~ m#^/categories/software/store/.*#">
# All old store pages now invalid, go to main store.
RedirectMatch 301 .* /software-store/
</If>
# Regexes for each category of software to group them logically.
# And so that 1,000s of redirects don't get considered on each page load.
<If "%{REQUEST_URI} =~ m#^/categories/software/item/.*#">
# Loads and loads of redirect lines for pages with arbitrary rules to product pages.
Redirect 301 "/categories/software/item/foo" /software-store/games/foo
Redirect 301 "/categories/software/item/bar" /software-store/productivity/bar
Redirect 301 "/categories/software/item/baz" /software-store/misc/baz
# ...
</If>
<If "%{REQUEST_URI} =~ m#^/categories/software/dlc/.*#">
# Loads and loads of redirect lines. It could also be grouped into subdirectories of dlc/ and so on.
# ...
</If>
</If>
# ...
Для огромного каталога несколько охраняющих регулярных выражений могут предотвратить тысячи бесполезных тестов.
Я использую Apache 2.4, где доступна директива <If>, но указанные выше директивы не дают ожидаемого эффекта. Внутренние <If> полностью игнорируются.
Если я удалю закрывающий <If> и оставлю только самые внутренние <If>, правила будут работать, поэтому я не верю, что мой синтаксис или мои правила перенаправления виноваты.
Я подозреваю, что проблема в том, что я не могу вложить <If>, хотя это кажется очень обычным делом. Я не вижу никаких ссылок на вложение, разрешенное или иное, в документации. http://httpd.apache.org/docs/2.4/mod/core.html#if
Могу ли я вложить директивы <If>? И если это так / если нет, не могли бы вы указать мне на раздел документации, в котором говорится, почему.
Обновленный ответ:
Начиная с Apache 2.4.26 вложено <If>
директивы разрешены.
В журнал изменений отметил следующее изменение:
Оцените вложенные блоки конфигурации If / ElseIf / Else. [Лука Тоскано, Джейкоб Чемпион]
Оригинальный ответ:
An <If>
директива не может быть вложена в другую <If>
директива, но может быть вложена в другие разделы, например <Directory>
, <Location>
, <Files>
и <IfModule>
.
В Документация Apache 2.4 для директивы If имеет следующее уведомление:
Не скриптовый язык
Имя этой директивы хорошо знакомо программистам и администраторам, но не следует путать ее с ее аналогом в языках сценариев. Например, текущая реализация не рассматривает возможность наличия
<If>
раздел внутри другого (внутренний<If>
будут проигнорированы).
Причина, по которой они решили не разрешать вложенные <If>
директивы.
Единственный предоставлена другая информация о гнездовании в документации указано, что каждый тип раздела отличается в зависимости от того, может ли он быть вложенным:
Вложенность разделов
Некоторые типы разделов могут быть вложены в другие типы разделов. С одной стороны,
<Files>
можно использовать внутри<Directory>
. С другой стороны,<If>
можно использовать внутри<Directory>
,<Location>
, и<Files>
разделы (но не внутри другого<If>
). Копии регулярных выражений указанного раздела ведут себя идентично.
Apache не обязательно «читает» конфигурации «по порядку», а скорее проходит довольно сложный процесс слияния. Из-за этого иногда трудно предсказать наилучшее «совпадение», и почти всегда требуется учитывать директивы, появляющиеся во всех различных разделах конфигурации.
Вы можете просмотреть документация по разделам конфигурации, уделяя особое внимание как разделы объединяются чтобы лучше это понять.
Также обратите внимание, что вы можете получить лучшие результаты, добавив такие директивы, как <Else> и <ElseIf>.