it-swarm.com.de

Tipps zum Debuggen von .htaccess-Umschreibregeln

Viele Poster haben Probleme beim Debuggen ihrer RewriteRule- und RewriteCond-Anweisungen in ihren .htaccess Dateien. Die meisten von ihnen verwenden einen gemeinsam genutzten Hosting-Dienst und haben daher keinen Zugriff auf die Stammserverkonfiguration. Sie können es nicht vermeiden, .htaccess - Dateien zum Umschreiben zu verwenden und kann nicht ein RewriteLogLevel zu aktivieren, wie viele Befragte vorschlagen. Außerdem gibt es viele .htaccess - spezifische Fallstricke und Einschränkungen Die Einrichtung eines lokalen Test-LAMP-Stacks ist für die meisten zu aufwändig.

Also meine Frage hier ist, wie würden wir empfehlen, dass sie debuggen ihre Regeln sich selbst =. Ich gebe unten ein paar Vorschläge. Andere Vorschläge wären willkommen.

  1. Verstehen Sie, dass die Mod_rewrite-Engine die Dateien .htaccess Durchläuft . Der Motor führt diese Schleife aus:

    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
    

    Ihre Regeln werden also wiederholt ausgeführt, und wenn Sie den URI-Pfad ändern, werden möglicherweise andere .htaccess - Dateien ausgeführt, falls vorhanden. Stellen Sie daher sicher, dass Sie diese Schleife beenden, indem Sie gegebenenfalls RewriteCond hinzufügen, um das Auslösen von Regeln zu stoppen. Löschen Sie auch alle neu geschriebenen Regelsätze mit niedrigerer Ebene .htaccess, Es sei denn, Sie beabsichtigen ausdrücklich, Regelsätze mit mehreren Ebenen zu verwenden.

  2. Vergewissern Sie sich, dass die Syntax der einzelnen Regexp korrekt ist , indem Sie anhand einer Reihe von Testmustern prüfen, ob es sich um eine gültige Syntax handelt und was Sie beabsichtigen eine vollständige Palette von Test-URIs. Siehe Antwort unten für weitere Details.

  3. Erstellen Sie Ihre Regeln inkrementell in einem Testverzeichnis. Sie können die Funktion "Ausführen der tiefsten Datei .htaccess Im Pfad" verwenden. Hier können Sie ein separates Testverzeichnis (Baumstruktur) einrichten und Regelsätze debuggen, ohne Ihre Hauptregeln zu vermasseln und die Arbeit Ihrer Site zu unterbrechen. Sie müssen sie einzeln hinzufügen, da dies die einzige Möglichkeit ist, Fehler an einzelnen Regeln zu lokalisieren.

  4. Verwenden Sie einen Dummy-Script-Stub, um Server- und Umgebungsvariablen auszulagern . (Siehe Listing 2 ) Wenn Ihre App beispielsweise blog/index.php Verwendet, können Sie dies in test/blog/index.php Kopieren und verwenden Hiermit können Sie Ihre Blog-Regeln im Unterverzeichnis test testen. Sie können auch Umgebungsvariablen verwenden, um sicherzustellen, dass die Rewrite-Engine Substitutionszeichenfolgen korrekt interpretiert, z.

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

    und suchen Sie nach diesen REDIRECT _ * Variablen im phpinfo-Dump. Übrigens, ich habe dieses verwendet und auf meiner Website festgestellt, dass ich stattdessen %{ENV:DOCUMENT_ROOT_REAL} Verwenden musste. Bei einer Redirector-Schleife listen REDIRECT_REDIRECT _ * -Variablen den vorherigen Durchgang auf. Usw..

  5. Stellen Sie sicher, dass Sie nicht von Ihrem Browser gebissen werden, der falsche 301-Weiterleitungen zwischenspeichert . Siehe Antwort unten . Mein Dank geht an lrich Palha dafür.

  6. Die Rewrite-Engine scheint empfindlich auf kaskadierte Regeln innerhalb eines .htaccess - Kontexts zu reagieren (hier führt ein RewriteRule zu einer Substitution, was allerdings auf weitere Regeln zurückzuführen ist), da ich Fehler mit internen Unterregeln gefunden habe. fordert (1) und fehlerhafte PATH_INFO -Verarbeitung an, die häufig mit [NS], [L] verhindert werden kann und [PT] Flags.

Noch mehr Kommentare oder Vorschläge?

Listing 1 - phpinfo

<?php phpinfo(INFO_ENVIRONMENT|INFO_VARIABLES);
262
TerryE

Im Folgenden finden Sie einige zusätzliche Tipps zum Testen von Regeln, die das Debuggen für Benutzer auf gemeinsam genutztem Hosting erleichtern können

1. Verwenden Sie einen Fake-User-Agenten

Fügen Sie beim Testen einer neuen Regel eine Bedingung hinzu, um sie nur mit einem fake Benutzeragenten auszuführen, den Sie für Ihre Anforderungen verwenden. Auf diese Weise wirkt sich dies nicht auf andere Personen auf Ihrer Website aus.

z.B

#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] 

Wenn Sie Firefox verwenden, können Sie den ser Agent Switcher verwenden, um die gefälschte User Agent-Zeichenfolge zu erstellen und zu testen.

2. Verwenden Sie 301 erst, wenn Sie mit dem Testen fertig sind

Ich habe so viele Posts gesehen, in denen Leute immer noch ihre Regeln testen und 301 verwenden. NICHT .

Wenn Sie Vorschlag 1 nicht auf Ihrer Website verwenden, sind nicht nur Sie, sondern auch alle anderen, die Ihre Website zu diesem Zeitpunkt besuchen, von der 301 betroffen.

Denken Sie daran, dass sie permanent sind und von Ihrem Browser aggressiv zwischengespeichert werden. Verwenden Sie stattdessen eine 302, bis Sie sicher sind, und ändern Sie sie dann in eine 301.

3. Denken Sie daran, dass 301 in Ihrem Browser aggressiv zwischengespeichert werden

Wenn Ihre Regel nicht funktioniert und es für Sie richtig aussieht und Sie die Vorschläge 1 und 2 nicht verwendet haben, testen Sie sie erneut, nachdem Sie den Browser-Cache geleert haben oder während Sie im privaten Browsing sind.

4. Verwenden Sie ein HTTP-Capture-Tool

Verwenden Sie ein HTTP-Capture-Tool wie Fiddler , um den tatsächlichen HTTP-Verkehr zwischen Ihrem Browser und dem Server anzuzeigen.

Während andere sagen könnten, dass Ihr site does not look right, Könnten Sie stattdessen all of the images, css and js are returning 404 errors Sehen und melden, wodurch das Problem schnell eingegrenzt wird.

Während andere melden, dass Sie started at URL A and ended at URL C Sind, können Sie sehen, dass sie bei URL A, were 302 redirected to URL B and 301 redirected to URL C Begonnen haben. Auch wenn URL C das ultimative Ziel war, werden Sie wissen, dass dies schlecht für SEO ist und behoben werden muss.

Sie können Cache-Header sehen, die auf der Serverseite festgelegt wurden, Anforderungen wiedergeben und Anforderungsheader zum Testen ändern.


127
Ulrich Palha

Online .htaccess-Test zum Umschreiben

Ich fand this Googeln für die RegEx-Hilfe, es ersparte mir viel Zeit, jedes Mal, wenn ich eine kleine Änderung vornehme, neue .htaccess - Dateien hochladen zu müssen.

von der Seite:

htaccess-Tester

Um die Schreibregeln für htaccess zu testen, geben Sie einfach die URL ein, auf die Sie die Regeln anwenden, platzieren Sie den Inhalt Ihres htaccess im größeren Eingabebereich und klicken Sie auf die Schaltfläche "Jetzt prüfen".

75
JCastell

Vergessen Sie nicht, dass es sich bei .htaccess-Dateien um eine relative URL handelt, die übereinstimmt.

In einer .htaccess-Datei wird die folgende RewriteRule niemals übereinstimmen:

RewriteRule ^/(.*)     /something/$s
12

Stellen Sie sicher, dass die Syntax der einzelnen Regexp korrekt ist

testen Sie anhand einer Reihe von Testmustern, um sicherzustellen, dass es sich um eine gültige Syntax handelt und das tut, was Sie mit einer Reihe von Test-URIs beabsichtigen.

In regexpCheck.php unten finden Sie ein einfaches Skript, das Sie zu einem privaten/test-Verzeichnis auf Ihrer Site hinzufügen können, um dies zu unterstützen. Ich habe mich eher kurz als hübsch gefasst. Einfach in eine Datei einfügen regexpCheck.php in einem Testverzeichnis, um es auf Ihrer Website zu verwenden. Auf diese Weise können Sie alle regulären Ausdrücke aufbauen und dabei anhand einer Liste von Testfällen testen. Ich verwende hier die PHP PCRE-Engine, aber nachdem ich mir die Apache-Quelle angesehen habe, ist diese im Grunde mit der in Apache verwendeten identisch. Es gibt viele HowTos und Tutorials, die Vorlagen bereitstellen und können helfen Ihnen beim Aufbau Ihrer Regexp-Fähigkeiten.

Listing 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>
8
TerryE

Stellen Sie sicher, dass Sie das Prozentzeichen vor den Variablen und nicht das Dollarzeichen verwenden.

Es ist %{HTTP_Host}, nicht${HTTP_Host}. Es gibt nichts im error_log, es gibt keine internen Serverfehler, Ihr regulärer Ausdruck ist immer noch korrekt, die Regel stimmt einfach nicht überein. Dies ist wirklich abscheulich, wenn Sie mit Django/genshi-Vorlagen viel arbeiten und ${} für variable Substitution im Muskelgedächtnis.

6
Simon

Eine von ein paar Stunden, die ich verschwendet habe:

Wenn Sie alle diese Tipps angewendet haben und nur 500 Fehler auftreten, weil Sie keinen Zugriff auf das Serverfehlerprotokoll haben, liegt das Problem möglicherweise nicht in der .htaccess-Datei, sondern in den Dateien, zu denen umgeleitet wird.

Nachdem ich mein .htaccess-Problem behoben hatte, verbrachte ich zwei weitere Stunden damit, es zu beheben, obwohl ich einige Berechtigungen einfach vergessen hatte.

6
Ruben

Setze Umgebungsvariablen und benutze Header, um sie zu erhalten:

Sie können neue Umgebungsvariablen mit RewriteRule-Zeilen erstellen, wie von OP erwähnt:

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

Aber wenn Sie kein serverseitiges Skript zum Laufen bringen können, wie können Sie dann diese Umgebungsvariable lesen? Eine Lösung besteht darin, einen Header zu setzen:

Header set TEST_FOOBAR "%{REDIRECT_TEST0}e"

Der Wert akzeptiert Formatbezeichner , einschließlich des %{NAME}e Bezeichner für Umgebungsvariablen (Kleinbuchstaben e nicht vergessen). Manchmal müssen Sie das REDIRECT_ Präfix, aber ich habe nicht herausgefunden, wann das Präfix hinzugefügt wird und wann nicht.

6
Flimm

Wenn Sie Umleitungen erstellen, testen Sie mit locken , um Probleme mit dem Browser-Caching zu vermeiden. Verwenden Sie -I, um nur http-Header abzurufen. Verwenden Sie -L, um allen Umleitungen zu folgen.

4
flm

In Bezug auf 4. müssen Sie immer noch sicherstellen, dass Ihr "Dummy-Skript-Stub" tatsächlich die Ziel-URL ist, nachdem das Umschreiben abgeschlossen ist, oder Sie werden nichts sehen!

Ein ähnlicher/verwandter Trick (siehe diese Frage ) ist das Einfügen einer temporären Regel wie:

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

Wo show.php ist ein sehr einfaches Skript, das nur sein $_GET Parameter (Sie können auch Umgebungsvariablen anzeigen, wenn Sie möchten).

Dies stoppt das Umschreiben an dem Punkt, an dem Sie es in den Regelsatz einfügen, ähnlich einem Haltepunkt in einem Debugger.

Wenn Sie Apache <2.3.9 verwenden, müssen Sie [L] eher, als [END], und Sie müssen möglicherweise Folgendes hinzufügen:

RewriteRule ^show.php$ - [L]

Geben Sie ganz oben in Ihrem Regelsatz ein, wenn die URL /show.php wird gerade neu geschrieben.

3
Doin

Ich habe diese Frage gefunden, als ich versucht habe, meine Probleme mit mod_rewrite zu debuggen, und sie hat definitiv einige hilfreiche Tipps. Am Ende ist es jedoch am wichtigsten, sicherzustellen, dass Ihre Regex-Syntax korrekt ist. Aufgrund von Problemen mit meiner eigenen RE-Syntax war die Installation des Skripts regexpCheck.php keine praktikable Option.

Da Apache jedoch Perl-kompatible reguläre Ausdrücke (Perl-Compatible Regular Expressions, PCRE) verwendet, sollte jedes Tool, das beim Schreiben von PCREs hilft, Abhilfe schaffen. Ich habe RegexPlanets Tool in der Vergangenheit mit Java und Javascript REs verwendet und war froh, dass sie auch Perl unterstützen.

Geben Sie einfach Ihren regulären Ausdruck und eine oder mehrere Beispiel-URLs ein und erfahren Sie, ob der reguläre Ausdruck (eine "1" in der Spalte "~ =") und gegebenenfalls alle übereinstimmenden Gruppen (die Zahlen in der Spalte "split") übereinstimmen. Die Spalte entspricht den von Apache erwarteten Zahlen (z. B. $ 1, $ 2 usw.) für jede URL. Sie behaupten, dass die PCRE-Unterstützung "in der Beta" ist, aber es war genau das, was ich brauchte, um meine Syntaxprobleme zu lösen.

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

Ich hätte einfach einen Kommentar zu einer vorhandenen Antwort hinzugefügt, aber mein Ruf ist noch nicht so hoch. Hoffe das hilft jemandem.

3
Lambart

Einige Fehler, die ich beobachtet habe, treten beim Schreiben von .htaccess Auf

Die wiederholte Verwendung von ^(.*)$ in mehreren Regeln, die Verwendung von ^(.*)$ führt in den meisten Fällen dazu, dass andere Regeln nicht mehr gültig sind, da sie mit der gesamten URL in einem einzigen Treffer übereinstimmen.

Wenn wir also die Regel für diese URL sapmle/url Verwenden, wird auch diese URL sapmle/url/string Verwendet.


[L] Flag sollte verwendet werden, um sicherzustellen, dass unsere Regel verarbeitet wurde.


Sollte wissen über:

nterschied in% n und $ n

%n Wird während des Teils %{RewriteCond} Abgeglichen, und $n Wird für den Teil %{RewriteRule} Abgeglichen.

Arbeiten von RewriteBase

Die RewriteBase-Direktive gibt das URL-Präfix an, das für verzeichnisbezogene (htaccess) RewriteRule-Direktiven verwendet werden soll, die einen relativen Pfad ersetzen.

Diese Anweisung ist erforderlich, wenn Sie einen relativen Pfad in einer Ersetzung im verzeichnisbezogenen Kontext (htaccess) verwenden, es sei denn, eine der folgenden Bedingungen ist erfüllt:

Die ursprüngliche Anforderung und die Ersetzung befinden sich unter dem DocumentRoot (im Gegensatz zu einer Erreichbarkeit mit anderen Mitteln, wie z. B. Alias). Der Dateisystempfad zu dem Verzeichnis, in dem sich die RewriteRule befindet, gefolgt von der relativen Ersetzung, ist auch als URL-Pfad auf dem Server gültig (dies ist selten). In Apache HTTP Server 2.4.16 und höher kann diese Anweisung weggelassen werden, wenn die Anforderung über Alias ​​oder mod_userdir zugeordnet wird.

2
Abhishek Gurjar

Wenn Sie mehr als nur eine Regelzeile in .htacesss schreiben möchten,
Denken Sie nicht einmal daran, eine dieser Hotfix-Methoden zum Debuggen zu verwenden.

Ich habe Tage damit verbracht, mehrere Regeln ohne Rückmeldung von LOGs festzulegen, um schließlich aufzugeben.
Ich habe Apache auf meinem PC installiert, die gesamte Site auf die Festplatte kopiert und den gesamten Regelsatz mithilfe der Protokolle sehr schnell aussortiert.
Dann überprüfte ich meine alten Regeln, die funktionierten. Ich sah, dass sie nicht wirklich das taten, was erwünscht war. Eine Zeitbombe mit einer etwas anderen Adresse.

Es gibt so viele Fallstricke bei Umschreiberegeln, dass es überhaupt keine logische Sache ist.
Sie können Apache in zehn Minuten zum Laufen bringen, es ist 10 MB, gute Lizenz, * NIX/WIN/MAC-fähig, auch ohne Installation.
Überprüfen Sie auch die Kopfzeilen Ihres Servers und holen Sie sich die gleiche Version von Apache aus dem Archiv, falls sie alt ist. Mein OP ist immer noch auf 2.0; Viele Dinge werden nicht unterstützt.

1
papo

(Ähnlich wie bei Doin idea) Um zu zeigen, was abgeglichen wird, verwende ich diesen Code

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

Speichern Sie es in r.php im Server-Stammverzeichnis und führen Sie dann einige Tests in .htaccess durch
Zum Beispiel möchte ich URLs zuordnen, die nicht mit einem Sprachpräfix beginnen

RewriteRule ^(?!(en|de)/)(.*)$ /r.php?$1&$2 [L] #$1&$2&...
RewriteRule ^(.*)$ /r.php?nomatch [L] #report nomatch and exit
0
UnLoCo

Ich lasse das hier, vielleicht ein offensichtliches Detail, aber habe mich stundenlang mit dem Kopf schlagen lassen: Sei vorsichtig mit %{REQUEST_URI} weil das, was @ Krist van Besien in seiner Antwort sagt, völlig richtig ist, aber nicht für den REQUEST_URI-String , weil der Die Ausgabe von TestString beginnt mit einem /. Also pass auf dich auf:

RewriteCond %{REQUEST_URI} ^/assets/$  
                            ^
                            | check this pesky fella right here if missing
0
Gruber