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.
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.
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.
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.
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..
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.
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?
<?php phpinfo(INFO_ENVIRONMENT|INFO_VARIABLES);
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
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.
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.
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.
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.
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".
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
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.
<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> </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"> 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> </p>
<table><thead><tr><td><b>Test Vector</b></td><td> <b>Result</b></td>
<?php
for ( $i=0; $i<$maxM; $i++ ) echo "<td> <b>\$$i</b></td>";
echo "</tr><tbody>\n";
for( $i=0; $i<$a_ntests; $i++ ){
echo '<tr><td> <input name="test[]" value="',
htmlentities($a_test[$i], ENT_QUOTES,"UTF-8"),'" /></td>';
foreach ($res[$i] as $v) { echo '<td> ',htmlentities($v, ENT_QUOTES,"UTF-8"),' </td>';}
echo "</tr>\n";
}
?> </table></form></body></html>
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.
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.
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.
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.
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.
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.
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:
%n
Wird während des Teils %{RewriteCond}
Abgeglichen, und $n
Wird für den Teil %{RewriteRule}
Abgeglichen.
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.
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.
(Ä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
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