Назад | Перейти на главную страницу

mod_rewrite таинственным образом добавляет подпапку к переписанному URL-адресу

РЕДАКТИРОВАТЬ: [Решено] Наконец нашел решение в документации; отправил ответ. Вкратце: DPI флаг.

РЕДАКТИРОВАТЬ: внизу добавлен простой способ воспроизвести проблему в Интернете.

Я потратил несколько часов на отладку некоторых изменений. Все хорошо, кроме одного поведения, которое меня ставит в тупик.

Каким-то образом при загрузке URL-адреса с двумя или более подкаталогами mod_rewrite автоматически добавляет все подкаталоги (кроме первого) к перезаписанному URL-адресу. Вот простейший пример, к которому я мог бы это свести. Это в htaccess по адресу DOCUMENT_ROOT.

Где это stripthat родом из? Может ли это быть причиной этого?

Я попытался разделить подпапки с помощью множества правил. Например:

Как ни странно, это происходит как на локальном xampp x Apache 2.4.7, так и на удаленном CentOS x Apache 2.2.

Я проверял перезаписанные URL-адреса, выводя их в сценарий, но вот способ воспроизвести проблему в Интернете.

Как воспроизвести это в Интернете

Для правил вставьте это:

# the `(?!)` negative lookaheads are just to make triple sure
# we're not running the same rules multiple times
RewriteRule ^(?!m[yo])([^/]+) my_$1
#RewriteRule ^(?!mo])\D*(\d+) mo_$1:$1:$1
  1. Выполнить: вывод http://example.com/my_a/123/b
  2. Раскомментируйте вторую строку.
  3. Выполнить: вывод http://example.com/mo_123:123:123/b
  4. Закомментируйте вторую строку, измените первую строку на RewriteRule ^(?!m[yo])([^/]+).*$ my_$1: проблема исчезнет на этом сайте, но не на моих серверах.

Мы будем очень благодарны за любые идеи.

[DPI] (discardpathinfo)

После нескольких часов испытаний и недоумения я вернулся в документация и нашел решение: [DPI] флаг.

Флаг DPI заставляет отбрасывать часть PATH_INFO перезаписанного URI.

Этот флаг доступен в версии 2.2.12 и новее.

В контексте каталога URI, с которым сравнивается каждый RewriteRule, представляет собой конкатенацию текущих значений URI и PATH_INFO.

Текущий URI может быть начальным URI по запросу клиента, результатом предыдущего раунда обработки mod_rewrite или результатом предыдущего правила в текущем раунде обработки mod_rewrite.

Напротив, PATH_INFO, который добавляется к URI перед каждым правилом, отражает только значение PATH_INFO перед этим циклом обработки mod_rewrite. Как следствие, если большие части URI сопоставляются и копируются в замену в нескольких директивах RewriteRule, независимо от того, какие части URI пришли из текущего PATH_INFO, к окончательному URI может быть добавлено несколько копий PATH_INFO.

Используйте этот флаг для любой замены, где PATH_INFO, полученный в результате предыдущего сопоставления этого запроса с файловой системой, не представляет интереса. Этот флаг навсегда забывает PATH_INFO, установленный до начала этого раунда обработки mod_rewrite. PATH_INFO не будет пересчитываться, пока не завершится текущий раунд обработки mod_rewrite. Последующие правила во время этого раунда обработки будут видеть только прямой результат замен без добавления PATH_INFO.

Возможно, вам не хватает конечного $ в твоем RewriteRule выражение, следовательно, материал не соответствует полностью?

Вы можете подумать о переходе на nginx; у него очень четкая и разумная документация, без раздувания и недетерминизма, которыми так знаменит Apache.