Советы по отладке .htaccess переписать правила - PullRequest
260 голосов
/ 06 февраля 2012

На многих авторах возникают проблемы с отладкой операторов RewriteRule и RewriteCond в файлах .htaccess. Большинство из них используют службу общего хостинга и поэтому не имеют доступа к конфигурации корневого сервера. Они не могут избежать использования .htaccess файлов для перезаписи, а не могут включить RewriteLogLevel ", как предлагают многие респонденты. Также есть много .htaccess -конкретных ловушек и ограничений, которые не очень хорошо освещены. Настройка локального Тестовый стек LAMP включает в себя слишком много кривой обучения для большинства.

Итак, мой вопрос здесь: как бы мы порекомендовали им отладить свои правила самим . Я приведу несколько предложений ниже. Буду признателен за другие предложения.

  1. Поймите, что механизм mod_rewrite циклически просматривает .htaccess файлы . Двигатель работает по этой петле:

    do
      execute server and vhost rewrites (in the Apache Virtual Host Config)
      find the lowest "Per Dir" .htaccess file on the file path with rewrites enabled
      if found(.htaccess)
         execute .htaccess rewrites (in the user's directory)
    while rewrite occurred
    

    Таким образом, ваши правила будут выполняться неоднократно, и если вы измените путь URI, то это может привести к выполнению других файлов .htaccess, если они существуют. Поэтому убедитесь, что вы прервите этот цикл, если необходимо, добавив дополнительные RewriteCond, чтобы остановить запуск правил. Также удалите все более низкие уровни .htaccess переписать наборы правил, если явно не намерены использовать многоуровневые наборы правил.

  2. Убедитесь, что синтаксис каждого регулярного выражения правильный , проверив набор тестовых шаблонов, чтобы убедиться, что это допустимый синтаксис и что вы собираетесь с полным диапазоном тестовых URI , См. ответ ниже для получения более подробной информации.

  3. Постепенно создавайте свои правила в тестовом каталоге. Вы можете использовать «выполнить самый глубокий файл .htaccess для функции пути», чтобы создать отдельный тестовый каталог (дерево ) и отлаживать здесь наборы правил, не нарушая основных правил и не останавливая работу вашего сайта. Вы должны добавлять их по одному, потому что это единственный способ локализовать ошибки в отдельных правилах.

  4. Использование заглушки сценария для вывода переменных сервера и среды . (См. Листинг 2 ) Если ваше приложение использует, скажем, blog/index.php, вы можете скопировать его в test/blog/index.php и использовать его для проверки правил блога в подкаталоге test. Вы также можете использовать переменные окружения, чтобы убедиться, что механизм перезаписи правильно интерпретирует строки подстановки, например,

    RewriteRule ^(.*) - [E=TEST0:%{DOCUMENT_ROOT}/blog/html_cache/$1.html]
    

    и найдите эти REDIRECT _ * переменные в дампе phpinfo. Кстати, я использовал этот и обнаружил на моем сайте, что я должен был использовать %{ENV:DOCUMENT_ROOT_REAL} вместо этого. В случае зацикливания редиректора Переменные REDIRECT_REDIRECT _ * перечисляют предыдущий проход. Etc ..

  5. Убедитесь, что ваш браузер не укушен неправильным кэшированием 301 перенаправлений . См. ответ ниже . Спасибо Ульриху Палье за это.

  6. Механизм перезаписи кажется чувствительным к каскадным правилам в контексте .htaccess (то есть, когда RewriteRule приводит к подстановке, а это относится к дальнейшим правилам), как я обнаружил ошибки с внутренними подпрограммами. запросы (1) и неправильная PATH_INFO обработка, которую часто можно предотвратить с помощью флагов [NS], [L] и [PT].

Есть еще комментарии или предложения?

Листинг 1 - phpinfo

<?php phpinfo(INFO_ENVIRONMENT|INFO_VARIABLES);

Ответы [ 14 ]

2 голосов
/ 27 марта 2017

Некоторые ошибки, которые я наблюдал, случаются при написании .htaccess

Повторное использование ^(.*)$ в нескольких правилах, использование ^(.*)$ приводит к тому, что в большинстве случаев другие правила оказываются бессильными, поскольку оно соответствует всем URL-адресам в одном обращении.

Итак, если мы используем правило для этого URL-адреса sapmle/url, оно также будет использовать этот URL-адрес sapmle/url/string.


[L] флаг должен использоваться, чтобы убедиться, что наше правило завершило обработку.


Должен знать о:

Разница в% n и $ n

%n сопоставляется во время %{RewriteCond} части, а $n совпадает с %{RewriteRule} части.

Работа RewriteBase

Директива RewriteBase указывает префикс URL, который будет использоваться для директивы RewriteRule для каждого каталога (htaccess), которые заменяют относительный путь.

Эта директива требуется, когда вы используете относительный путь в подстановка в контексте каталога (htaccess), если только выполняются следующие условия:

Первоначальный запрос и замена находятся под DocumentRoot (в отличие от достижимых другими средствами, такими как Alias). Путь файловой системы к каталогу, содержащему RewriteRule, суффикс относительной замены также действителен как URL-путь на сервер (это редко). В Apache HTTP Server 2.4.16 и новее эта директива может быть опущена, когда запрос отображается через псевдоним или mod_userdir.

1 голос
/ 28 января 2017

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

Я потратил впустую дни, устанавливая несколько правил, без обратной связи с журналами, только чтобы окончательно сдаться.
Я установил Apache на свой компьютер, скопировал весь сайт на его жесткий диск и очень быстро разобрал весь набор правил, используя журналы.
Затем я пересмотрел свои старые правила, которые работали. Я видел, что они действительно не делали то, что хотели. Часовая бомба с немного другим адресом.

В правилах переписывания так много ошибок, что это не совсем логичная вещь.
Вы можете запустить и запустить Apache за десять минут, его 10 МБ, хорошая лицензия, * NIX / WIN / MAC готовы, даже без установки.
Также проверьте строки заголовка вашего сервера и получите ту же версию Apache из их архива, если она старая. Мой ОП все еще на 2.0; многие вещи не поддерживаются.

0 голосов
/ 04 сентября 2015

Я оставлю это здесь, возможно, очевидную деталь, но заставил меня несколько часов биться головой: будьте осторожны, используя %{REQUEST_URI}, потому что то, что @ Krist van Besien говорит в своем ответе, совершенно верно, , но не для строки REQUEST_URI , поскольку выход этой TestString начинается с /.Поэтому будьте осторожны:

RewriteCond %{REQUEST_URI} ^/assets/$  
                            ^
                            | check this pesky fella right here if missing
0 голосов
/ 14 октября 2013

(аналогично идее Doin) Чтобы показать, что совпадает, я использую этот код

$keys = array_keys($_GET);
foreach($keys as $i=>$key){
    echo "$i => $key <br>";
}

Сохраните его в r.php в корневом каталоге сервера, а затем проведите несколько тестов в .htaccess
Например, я хочу сопоставить URL-адреса, которые не начинаются с языкового префикса

RewriteRule ^(?!(en|de)/)(.*)$ /r.php?$1&$2 [L] #$1&$2&...
RewriteRule ^(.*)$ /r.php?nomatch [L] #report nomatch and exit
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...