Советы по отладке .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 ]

126 голосов
/ 09 февраля 2012

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

1.Использовать поддельный пользовательский агент

При тестировании нового правила добавьте условие, чтобы выполнять его только с пользовательским агентом fake, который вы будете использовать для своих запросов.Таким образом, это не повлияет ни на кого на вашем сайте.

например

#protect with a fake user agent
RewriteCond %{HTTP_USER_AGENT}  ^my-fake-user-agent$
#Here is the actual rule I am testing
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC] 
RewriteRule ^ http://www.domain.com%{REQUEST_URI} [L,R=302] 

Если вы используете Firefox, вы можете использовать User Agent Switcher для созданияподдельная строка агента пользователя и тест.

2.Не используйте 301, пока не закончите тестирование

Я видел очень много постов, где люди все еще тестируют свои правила и используют 301. DO NOT .

Если вы не используете предложение 1 на своем сайте, то не только вы, но и любой посетитель вашего сайта в это время будет затронут 301.

Помните, что они постоянны и агрессивнокэшируется вашим браузером.Вместо этого используйте 302, пока не будете уверены, затем измените его на 301.

3.Помните, что 301 агрессивно кэшируются в вашем браузере

Если ваше правило не работает, и оно выглядит правильным для вас, и вы не использовали предложения 1 и 2, то проведите повторную проверку после очистки кэша браузера или во времяприватный просмотр.

4.Используйте инструмент захвата HTTP

Используйте инструмент захвата HTTP, например Fiddler , чтобы увидеть фактический трафик HTTP между вашим браузером и сервером.

В то время как другие могут сказать, что ваш site does not look right, вы можете вместо этого увидеть и сообщить, что all of the images, css and js are returning 404 errors, быстро сужая проблему.

В то время как другие сообщат, что вы started at URL A and ended at URL C, высможет увидеть, что они начали в URL A, were 302 redirected to URL B and 301 redirected to URL C.Даже если URL C был конечной целью, вы будете знать, что это плохо для SEO и должно быть исправлено.

Вы сможете увидеть заголовки кэша, которые были установлены на стороне сервера, повторить запросы, изменитьзапросить заголовки для проверки ....


73 голосов
/ 06 февраля 2014

Онлайн тестирование перезаписи .htaccess

Я нашел это Поиск в Google для справки RegEx, это избавило меня от необходимости загружать новые .htaccess файлы каждый раз, когда я вносил небольшие изменения.

с сайта:

тестер htaccess

Чтобы проверить свои правила перезаписи htaccess, просто введите URL-адрес, к которому вы применяете правила, поместите содержимое вашего htaccess в большую область ввода и нажмите кнопку «Проверить сейчас».

12 голосов
/ 21 июня 2013

Не забывайте, что в файлах .htaccess это относительный URL, который соответствует.

В файле .htaccess следующий RewriteRule никогда не будет совпадать:

RewriteRule ^/(.*)     /something/$s
8 голосов
/ 13 февраля 2012

Убедитесь, что синтаксис каждого регулярного выражения правильный

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

См. regexpCheck.php ниже для простого скрипта, который вы можете добавить в личный каталог / test на вашем сайте, чтобы помочь вам сделать это. Я сохранил это краткое, а не красивое. Просто вставьте это в файл regexpCheck.php в тестовом каталоге, чтобы использовать его на своем сайте. Это поможет вам создать любое регулярное выражение и сравнить его со списком тестовых случаев. Я использую движок PHP PCRE, но, посмотрев на исходник Apache, он в основном идентичен тому, который используется в Apache. Существует множество инструкций и руководств, которые предоставляют шаблоны и могут помочь вам развить навыки регулярного выражения.

Листинг 1 - regexpCheck.php

<html><head><title>Regexp checker</title></head><body>
<?php 
    $a_pattern= isset($_POST['pattern']) ? $_POST['pattern'] : "";
    $a_ntests = isset($_POST['ntests']) ? $_POST['ntests'] : 1;
    $a_test   = isset($_POST['test']) ? $_POST['test'] : array();

    $res = array(); $maxM=-1; 
    foreach($a_test as $t ){
        $rtn = @preg_match('#'.$a_pattern.'#',$t,$m);
        if($rtn == 1){
            $maxM=max($maxM,count($m));
            $res[]=array_merge( array('matched'),  $m );
        } else {
            $res[]=array(($rtn === FALSE ? 'invalid' : 'non-matched'));
        }
    } 
?> <p>&nbsp; </p>
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME'];?>">
    <label for="pl">Regexp Pattern: </label>
    <input id="p" name="pattern" size="50" value="<?php echo htmlentities($a_pattern,ENT_QUOTES,"UTF-8");;?>" />
    <label for="n">&nbsp; &nbsp; Number of test vectors: </label>
    <input id="n" name="ntests"  size="3" value="<?php echo $a_ntests;?>"/>
    <input type="submit" name="go" value="OK"/><hr/><p>&nbsp;</p>
    <table><thead><tr><td><b>Test Vector</b></td><td>&nbsp; &nbsp; <b>Result</b></td>
<?php 
    for ( $i=0; $i<$maxM; $i++ ) echo "<td>&nbsp; &nbsp; <b>\$$i</b></td>";
    echo "</tr><tbody>\n";
    for( $i=0; $i<$a_ntests; $i++ ){
        echo '<tr><td>&nbsp;<input name="test[]" value="', 
            htmlentities($a_test[$i], ENT_QUOTES,"UTF-8"),'" /></td>';
        foreach ($res[$i] as $v) { echo '<td>&nbsp; &nbsp; ',htmlentities($v, ENT_QUOTES,"UTF-8"),'&nbsp; &nbsp; </td>';}
        echo "</tr>\n";
    }
?> </table></form></body></html>
6 голосов
/ 22 июля 2015

Установите переменные окружения и используйте заголовки для их получения:

Вы можете создавать новые переменные окружения со строками RewriteRule, как указано в OP:

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

Но если вы не можете заставить работать серверный скрипт, как вы можете тогда прочитать эту переменную среды? Одним из решений является установка заголовка:

Header set TEST_FOOBAR "%{REDIRECT_TEST0}e"

Значение принимает спецификаторы формата , включая спецификатор %{NAME}e для переменных среды (не забывайте строчную букву e). Иногда вам нужно добавить префикс REDIRECT_, но я не определился, когда префикс добавляется, а когда нет.

6 голосов
/ 04 февраля 2013

Один из пары часов, которые я потратил впустую:

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

После того, как я исправил свою проблему .htaccess, я потратил еще два часа, пытаясь ее исправить, хотя я просто забыл о некоторых разрешениях.

5 голосов
/ 29 января 2013

Убедитесь, что перед переменными используется знак процента, а не знак доллара.

Это %{HTTP_HOST}, , а не ${HTTP_HOST}.В error_log ничего не будет, не будет внутренних серверных ошибок, ваше регулярное выражение все еще верно, правило просто не будет соответствовать.Это действительно отвратительно, если вы много работаете с шаблонами django / genshi и имеете ${} для замены переменных в мышечной памяти.

4 голосов
/ 14 марта 2017

Если вы создаете перенаправления, протестируйте с curl , чтобы избежать проблем с кэшированием в браузере. Используйте -I для получения только заголовков http. Используйте -L для отслеживания всех перенаправлений.

3 голосов
/ 15 марта 2013

Что касается 4., вам все равно нужно убедиться, что ваша "заглушка сценария" действительно является целевым URL-адресом после того, как вся перезапись выполнена, иначе вы ничего не увидите!

Подобный / связанный трюк (см. этот вопрос ) заключается во вставке временного правила, такого как:

RewriteRule (.*) /show.php?url=$1 [END]

Где show.php - это очень простой скрипт, который просто отображает свои параметры $_GET (вы также можете отображать переменные окружения, если хотите).

Это остановит переписывание в том месте, где вы вставляете его в набор правил, как точка останова в отладчике.

Если вы используете Apache <2.3.9, вам нужно будет использовать <code>[L] вместо [END], и вам может , затем нужно добавить:

RewriteRule ^show.php$ - [L]

В самом верху вашего набора правил, , если , то URL /show.php сам переписывается.

3 голосов
/ 30 июля 2012

Я нашел этот вопрос, пытаясь отладить проблемы с mod_rewrite, и у него определенно есть несколько полезных советов. Но в конце самое главное, чтобы убедиться, что ваш синтаксис регулярных выражений правильный. Из-за проблем с моим собственным синтаксисом RE установка сценария regexpCheck.php не была приемлемой опцией.

Но поскольку Apache использует Perl-совместимые регулярные выражения (PCRE), любой инструмент, который помогает в написании PCRE, должен помочь. В прошлом я использовал инструмент RegexPlanet с Java и Javascript RE, и был рад обнаружить, что они также поддерживают Perl.

Просто введите свое регулярное выражение и один или несколько примеров URL-адресов, и он скажет вам, соответствует ли регулярное выражение («1» в столбце «~ =») и, если применимо, любые соответствующие группы (числа в Столбец «split» будет соответствовать числам, ожидаемым Apache, например, $ 1, $ 2 и т. д.) для каждого URL. Они утверждают, что поддержка PCRE находится "в бета-версии", но это было именно то, что мне было нужно для решения моих проблем с синтаксисом.

http://www.regexplanet.com/advanced/perl/index.html

Я бы просто добавил комментарий к существующему ответу, но моя репутация еще не на этом уровне. Надеюсь, это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...