Кажется, что в mod_rewrite
последнее время существует приличное количество потоков, которые немного не понимают, как работают определенные аспекты. В результате я составил несколько заметок об общих функциях и, возможно, несколько досадных нюансов.
Какие еще функции / общие проблемы вы использовали mod_rewrite
?
Ответы:
Где разместить правила mod_rewrite
mod_rewrite
правила могут быть размещены внутриhttpd.conf
файла или внутри.htaccess
файла. если у вас есть доступhttpd.conf
, размещение правил здесь даст преимущество в производительности (поскольку правила обрабатываются один раз, а не каждый раз при.htaccess
вызове файла).Ведение журнала запросов mod_rewrite
Ведение журнала можно включить из
httpd.conf
файла (в том числе<Virtual Host>
):Общие варианты использования
Чтобы направить все запросы в одну точку:
Начиная с Apache 2.2.16 вы также можете использовать
FallbackResource
.Обработка переадресации 301/302:
Примечание : внешние перенаправления неявно представляют собой перенаправления 302:
Принудительное использование SSL
Общие флаги:
[R]
или[redirect]
- принудительное перенаправление (по умолчанию временное перенаправление 302)[R=301]
или[redirect=301]
- принудительное перенаправление 301[L]
или[last]
- остановить процесс перезаписи (см. примечание ниже в распространенных ошибках)[NC]
или[nocase]
- укажите, что соответствие должно быть нечувствительным к региструИспользование длинных флагов часто более читабельно и поможет другим, кто придет прочитать ваш код позже.
Вы можете разделить несколько флагов запятой:
Общие подводные камни
Смешивание
mod_alias
стилей перенаправления сmod_rewrite
Примечание : вы можете смешивать
mod_alias
сmod_rewrite
, но это требует больше работы, чем просто обработка базовых перенаправлений, как указано выше.Контекст влияет на синтаксис
Внутри
.htaccess
файлов в шаблоне RewriteRule начальная косая черта не используется:[L] не последний! (иногда)
[L]
Флаг прекращает обработку какие - либо дополнительные правила перезаписи для этого прохода через набор правил . Однако, если URL-адрес был изменен в этом проходе, и вы находитесь в.htaccess
контексте или<Directory>
разделе, то ваш измененный запрос будет снова передан обратно через механизм синтаксического анализа URL-адресов. И на следующем проходе, на этот раз оно может соответствовать другому правилу. Если вы этого не понимаете, часто кажется, что ваш[L]
флаг не подействовал.Наш журнал перезаписи показывает, что правила выполняются дважды, а URL-адрес обновляется дважды:
Лучший способ обойти это - использовать
[END]
флаг ( см. Документацию Apache ) вместо[L]
флага, если вы действительно хотите остановить всю дальнейшую обработку правил (и последующие проходы). Однако[END]
флаг доступен только для Apache v2.3.9 + , поэтому, если у вас v2.2 или ниже, вы застряли только на[L]
флаге.В более ранних версиях вы должны полагаться на
RewriteCond
инструкции, чтобы предотвратить соответствие правил при последующих проходах механизма синтаксического анализа URL.Или вы должны убедиться, что ваши RewriteRule находятся в контексте (т.е.
httpd.conf
), который не приведет к повторному синтаксическому анализу вашего запроса.источник
[L]
Флаг означает , что правило является последним в текущей обработке, это не остановит перезапись, потому что они являются внутренними переадресовывает, поэтому вашdirB
обратиться кdirC
в следующей обработке HTAccess. Само собойRewriteRule ^(.*)$ index.php?query=$1
будет бесконечный цикл внутренних перенаправлений (на практике он завершается после 10 итераций). -1, потому что вы предполагаете, что [L] не последний . Это не прекращение процесса перезаписи, но последнее .RewriteCond %{HTTPS} off
что это предпочтительный способ проверки HTTPS-соединения (в вашем примере принудительногоесли вам нужно «заблокировать» внутренние перенаправления / перезаписи в .htaccess, взгляните на
состояние, как описано здесь .
источник
.*
с[L]
флагом я прочитал , прежде чем я получил здесь.200
,!=200
,^.
,^$
. Очевидно, переменная устанавливается200
для перенаправления, но также другие страницы (ошибки и прочее) устанавливают для нее какое-то значение. Теперь это означает , что вы либо проверить , если онis empty
,is not empty
,is 200
илиis not 200
, в зависимости от того, что вам нужно.Сделка с RewriteBase:
Вам почти всегда нужно устанавливать RewriteBase. Если вы этого не сделаете, apache предположит, что ваша база - это физический путь к вашему каталогу на диске. Итак, начнем с этого:
источник
RewriteBase .
или указать, что URL-адрес должен оставаться неизменным, просто изменив то, что вы указали?RewriteBase
если вы используете подстановку относительного пути вRewriteRule
директиве. Лучше избегать использования относительных путей.RewriteBase
полностью избегаем этого , поскольку почти все разработчики неправильно понимают, что он делает. Как сказал @ w3d, он вам нужен только в том случае, если вы хотите сохранить символы и хотите применить одну и ту же базу ко всем своим RewriteRules в одном файле. Ваш код, вероятно, будет понятнее для других, если вы его избегаете.Другие подводные камни:
1- Иногда рекомендуется отключить MultiViews
Я не очень разбираюсь во всех возможностях MultiViews, но я знаю, что он портит мои правила mod_rewrite, когда он активен, потому что одно из его свойств - попытаться «угадать» расширение файла, который, по его мнению, я ищу. ,
Я объясню: предположим, что у вас есть 2 файла php в вашем веб-каталоге, file1.php и file2.php, и вы добавляете эти условия и правило в свой .htaccess:
Вы предполагаете, что все URL-адреса, которые не соответствуют файлу или каталогу, будут захвачены file1.php. Сюрприз! Это правило не соблюдается для URL- адреса http: // myhost / file2 / somepath . Вместо этого вы попадаете в file2.php.
Что происходит, так это то, что MultiViews автоматически догадались, что URL-адрес, который вам действительно нужен, был http: //myhost/file2.php/somepath, и с радостью отправил вас туда.
Теперь вы не имеете ни малейшего представления о том, что только что произошло, и сомневаетесь в том, что, по вашему мнению, вы знали о mod_rewrite. Затем вы начинаете экспериментировать с правилами, пытаясь понять логику этой новой ситуации, но чем больше вы тестируете, тем меньше в этом смысла.
Хорошо, короче говоря, если вы хотите, чтобы mod_rewrite работал способом, приближенным к логике, отключение MultiViews - это шаг в правильном направлении.
2- включить FollowSymlinks
Я не знаю подробностей, но я видел, как он упоминается много раз, так что просто сделайте это.
источник
+FollowSymLinks
упоминается в документации как обязательный дляmod_rewrite
работы вообще из соображений безопасности.Уравнение может быть выполнено на следующем примере:
Динамическая балансировка нагрузки:
Если вы используете mod_proxy для балансировки вашей системы, можно добавить динамический диапазон рабочего сервера.
источник
Необходимо лучше понять флаг [L]. Флаг [L] стоит последним, вам просто нужно понять, что заставит ваш запрос снова маршрутизироваться через механизм синтаксического анализа URL. Из документов ( http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_l ) (выделено мной):
Так в [L] флаг делает остановку обработки любые дополнительные правила перезаписи для этого прохода через набор правил. Однако, если ваше правило, помеченное [L], изменило запрос, и вы находитесь в контексте .htaccess или
<Directory>
разделе, то ваш измененный запрос будет снова передан обратно через механизм синтаксического анализа URL. И на следующем проходе, на этот раз оно может соответствовать другому правилу. Если вы не понимаете, что произошло, похоже, ваше первое правило перезаписи с флагом [L] не подействовало.Лучший способ обойти это - использовать флаг [END] ( http://httpd.apache.org/docs/current/rewrite/flags.html#flag_end ) вместо флага [L], если вы действительно хотите остановить вся дальнейшая обработка правил (и последующий повторный анализ). Однако флаг [END] доступен только для Apache v2.3.9 +, поэтому, если у вас v2.2 или ниже, вы застряли только с флагом [L]. В этом случае вы должны полагаться на операторы RewriteCond, чтобы предотвратить сопоставление правил при последующих проходах механизма синтаксического анализа URL. Или вы должны убедиться, что ваши RewriteRule находятся в контексте (например, httpd.conf), который не приведет к повторному синтаксическому анализу вашего запроса.
источник
Еще одна замечательная функция - расширение rewrite-map. Они особенно полезны, если вам нужно обработать огромное количество хостов / перезаписей:
Они похожи на замену "ключ-значение":
Затем вы можете использовать сопоставление в своих правилах, например:
Более подробную информацию по этой теме можно найти здесь:
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#mapfunc
источник
.htaccess
перезапись на основе. В этом контексте это не работает.mod_rewrite может изменять аспекты обработки запросов без изменения URL-адреса, например, установка переменных среды, установка файлов cookie и т. д. Это невероятно полезно.
Условно установите переменную окружения:
Возвращает 503 ответа:
RewriteRule
«s[R]
флаг может занять не-3xx значение и возвращает без перенаправления ответа, например , для управляемого времени простоя / обслуживания:вернет ответ 503 (не перенаправление как таковое).
Кроме того, mod_rewrite может действовать как сверхмощный интерфейс для mod_proxy, поэтому вы можете делать это вместо написания
ProxyPass
директив:Мнение: Использование
RewriteRule
s иRewriteCond
s для маршрутизации запросов к различным приложениям или балансировщикам нагрузки на основе практически любого мыслимого аспекта запроса просто невероятно мощно. Контроль запросов на их пути к бэкэнду и возможность изменять ответы на обратном пути делает mod_rewrite идеальным местом для централизации всей конфигурации, связанной с маршрутизацией.Найдите время, чтобы изучить его, оно того стоит! :)
источник