Rewrite Regeln in der .htaccess Datei
Hugo Egon Balder
- webserver
Hallo Forum,
bei der Verwendung von mod_rewrite in der .htaccess habe ich einige Verständnisschwierigkeiten und die entsprechende http://de.selfhtml.org/servercgi/server/rewrite.htm@title=SELF-Seite hilft mir nicht weiter.
Bis heute habe ich das Wegfallen des 'www' beim Aufruf der Domain so gelöst:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
Das funktioniert auch. Kommen aber weitere mod_rewrite Geschehnisse dazu und die .hataccess wird umfangreicher, dann gibt es immer mehr Probleme. (Z.B. Stichwort Fremdverlinkung von Bildern)
Nun habe ich heute beim Googeln die Seite DARING FIREBALL - Using .htaccess Redirection to Standardize Web Server Addresses gefunden, auf der die Streichung des 'www' mit simplerem Code geschieht:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule (.*) http://example.com/$1 [R=Permanent]
Wenn ich _diese_ Lösung verwende, habe ich mit all den anderen mod_rewrite Geschehnissen viel weniger Probleme. (Was ich damit sagen will: Es kommt z.B. zu weniger Internal Server Errors.)
Nun meine Fragen:
1.) Ist die erste Möglichkeit die "schlechtere"? Wieso gibt es da mehr Probleme damit als bei der zweiten Lösung?
2.) Was ist denn in der RewriteRule-Zeile der Unterschied zwischen ^(.*)$ und (.*) am Beginn? Was genau bedeuten diese 2 EInleitungen in dieser Zeile?
3.) Gibt es eine empfehlenswerte Seite auf Deutsch, die mich in das Thema einführt?
Wie gesagt, ich habe ja nicht wirklich ein "Problem". Das, was ich will, nämlich den Wegfall des 'www' funktioniert ja. Mit beiden Lösungen. Aber es stört mich einfach, dass ich da was mache/was verwende, was ich eigentlich gar nicht verstehe. Nicht mal ansatzweise. Und da ich nicht blind was kopieren möchte, was mir ein anderer vorgesetzt hat, würd ich gerne wissen und verstehen, was da eigentlich passiert.
Deshalb Danke für jede Antwort!
Liebe Grüße
Hugo E.B.
Moin!
Bis heute habe ich das Wegfallen des 'www' beim Aufruf der Domain so gelöst:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]Das funktioniert auch. Kommen aber weitere mod_rewrite Geschehnisse dazu und die .hataccess wird umfangreicher, dann gibt es immer mehr Probleme. (Z.B. Stichwort Fremdverlinkung von Bildern)
Nun habe ich heute beim Googeln die Seite DARING FIREBALL - Using .htaccess Redirection to Standardize Web Server Addresses gefunden, auf der die Streichung des 'www' mit simplerem Code geschieht:
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule (.*) http://example.com/$1 [R=Permanent]
Spannend, dass du vier Zeilen (im Vergleich zu drei) mit mehr Zeichen pro Zeile als "simpler" betitelst.
Deine obere Lösung ist jedenfalls in der Hinsicht falsch, dass du die Punkte im Domainnamen in der RewriteCond nicht escapest - auf diese Weise wirken sie als Platzhalter für "jedes beliebige Zeichen" - das ist technisch nicht korrekt und gehört korrigiert.
Weiterhin hört deine obere Lösung nach der Ausgabe des Redirects sofort auf, weitere Regeln anzuwenden. Das ist im Prinzip nicht falsch, denn was könnte man danach mit der im Browser immer noch ursprünglichen URL MIT WWW denn noch umschreiben?
Insofern: Deine Beobachtung, dass es zu Problemen kommt, mag nicht falsch sein, aber anstatt irgendwas in deinem Rewriting zu ändern (wobei sich nichts ändert, außer dem L-Parameter für das Beenden des Rewriting nach dieser Regel), solltest du lieber erstmal die auftretenden Fehler analysieren und beschreiben.
Wenn ich _diese_ Lösung verwende, habe ich mit all den anderen mod_rewrite Geschehnissen viel weniger Probleme. (Was ich damit sagen will: Es kommt z.B. zu weniger Internal Server Errors.)
1.) Ist die erste Möglichkeit die "schlechtere"? Wieso gibt es da mehr Probleme damit als bei der zweiten Lösung?
Siehe oben.
2.) Was ist denn in der RewriteRule-Zeile der Unterschied zwischen ^(.*)$ und (.*) am Beginn? Was genau bedeuten diese 2 EInleitungen in dieser Zeile?
^ steht für den Stringanfang, $ für das Stringende. Es gibt im Ergebnis zwischen den beiden Ausdrücken ^(.*)$ (nimm alle beliebigen Zeichen zwischen Anfang und Ende) und (.*) (nimm alle beliebigen Zeichen, und zwar möglichst viele davon) keinen Unterschied: Alle werden immer den gesamten String finden.
3.) Gibt es eine empfehlenswerte Seite auf Deutsch, die mich in das Thema einführt?
Keine Ahnung, ob es die gibt. Das Manual vom Apache ist leider nicht auf deutsch erhältlich im Moment.
Wie gesagt, ich habe ja nicht wirklich ein "Problem". Das, was ich will, nämlich den Wegfall des 'www' funktioniert ja. Mit beiden Lösungen. Aber es stört mich einfach, dass ich da was mache/was verwende, was ich eigentlich gar nicht verstehe. Nicht mal ansatzweise. Und da ich nicht blind was kopieren möchte, was mir ein anderer vorgesetzt hat, würd ich gerne wissen und verstehen, was da eigentlich passiert.
Dann lerne mal zuallererst reguläre Ausdrücke. Wenn du die nicht kannst, dann ist jeder Versuch, Rewriting zu erlernen, zum Scheitern verurteilt.
- Sven Rautenberg
Hallo Sven,
Dann lerne mal zuallererst reguläre Ausdrücke.
danke für den Hinweis, kannst Du trotzedem meine Frage etwas präziser beantworten bitte?
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]
RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule (.*) http://example.com/$1 [R=Permanent]
Deine obere Lösung ist jedenfalls in der Hinsicht falsch, dass du die Punkte im Domainnamen in der RewriteCond nicht escapest - auf diese Weise wirken sie als Platzhalter für "jedes beliebige Zeichen" - das ist technisch nicht korrekt und gehört korrigiert.
Das heißt also, die 2. Möglichkeit ist besser?
Weiterhin hört deine obere Lösung nach der Ausgabe des Redirects sofort auf, weitere Regeln anzuwenden. Das ist im Prinzip nicht falsch, denn was könnte man danach mit der im Browser immer noch ursprünglichen URL MIT WWW denn noch umschreiben?
Ich nehme an, du meinst das L, richtig? Also soll ich es streichen? Oder stehen lassen?
Nachfrage: Wenn ich jetzt in der .htaccess weitere Regeln dazuschreibe, also zB. etwas zur Verhinderung einer Fremdverlinkung, muß/soll ich da jedes mal mit "RewriteEngine on" beginnen, oder reicht das _ein_ mal in der .hataccess, nämlich vor dem ersten mod_rewrite Geschehen? Oder darf dieses [L] nur nach dem allerletzten mod_rewriting in der .htaccess stehen?
^ steht für den Stringanfang, $ für das Stringende.
Verstehe. Ist das jetzt Wissen über Reguläre Ausdrücke oder Wissen über mod_rewriting?
Es gibt im Ergebnis zwischen den beiden Ausdrücken ^(.*)$ (nimm alle beliebigen Zeichen zwischen Anfang und Ende) und (.*) (nimm alle beliebigen Zeichen, und zwar möglichst viele davon) keinen Unterschied: Alle werden immer den gesamten String finden.
OK, aber was ist dann in diesem Zusammenhang richtiger/logischer ... aus der Sichet eines Profis angebrachter?
3.) Gibt es eine empfehlenswerte Seite auf Deutsch, die mich in das Thema einführt?
Keine Ahnung, ob es die gibt. Das Manual vom Apache ist leider nicht auf deutsch erhältlich im Moment.
Das ist schade. =(
Dann lerne mal zuallererst reguläre Ausdrücke.
Wie gesagt, das werde ich tun. Ich denke, dafür hab ich vorher auch eine sehr gute Seite gefunden.
MfG
Hugo E.B.
Hallo,
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]RewriteEngine on
RewriteBase /
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule (.*) http://example.com/$1 [R=Permanent]Deine obere Lösung ist jedenfalls in der Hinsicht falsch, dass du die Punkte im Domainnamen in der RewriteCond nicht escapest - auf diese Weise wirken sie als Platzhalter für "jedes beliebige Zeichen" - das ist technisch nicht korrekt und gehört korrigiert.
Das heißt also, die 2. Möglichkeit ist besser?
ja, "ist [...] falsch" spricht für mich eine deutliche Sprache. Deine Version führt trotzdem zum gewünschten Ergebnis, weil der Punkt in einem RegEx als Wildcard für "jedes beliebige Zeichen" steht, das schließt einen echten Punkt natürlich mit ein. Somit passt ^www.example.com$ selbstverständlich auf "www.example.com", eber ebensogut auch auf "www4example.com". Ist in deinem Fall nicht relevant, aber ich möchte das Prinzip klarmachen.
Weiterhin hört deine obere Lösung nach der Ausgabe des Redirects sofort auf, weitere Regeln anzuwenden. Das ist im Prinzip nicht falsch, denn was könnte man danach mit der im Browser immer noch ursprünglichen URL MIT WWW denn noch umschreiben?
Ich nehme an, du meinst das L, richtig? Also soll ich es streichen? Oder stehen lassen?
Stehenlassen, wenn weitere Regeln folgen, die in diesem Schritt nicht mehr relevant sind. Egal, wenn die Regel sowieso die letzte in der .htaccess ist.
Nachfrage: Wenn ich jetzt in der .htaccess weitere Regeln dazuschreibe, also zB. etwas zur Verhinderung einer Fremdverlinkung, muß/soll ich da jedes mal mit "RewriteEngine on" beginnen, oder reicht das _ein_ mal in der .hataccess, nämlich vor dem ersten mod_rewrite Geschehen?
Einmal die Engine anwerfen genügt. Oder versuchst du auch bei jedem Anfahren erst, den Motor erneut anzulassen? ;-)
Oder darf dieses [L] nur nach dem allerletzten mod_rewriting in der .htaccess stehen?
Genau dort ist es sinnlos.
^ steht für den Stringanfang, $ für das Stringende.
Verstehe. Ist das jetzt Wissen über Reguläre Ausdrücke oder Wissen über mod_rewriting?
Ersteres.
Es gibt im Ergebnis zwischen den beiden Ausdrücken ^(.*)$ (nimm alle beliebigen Zeichen zwischen Anfang und Ende) und (.*) (nimm alle beliebigen Zeichen, und zwar möglichst viele davon) keinen Unterschied: Alle werden immer den gesamten String finden.
OK, aber was ist dann in diesem Zusammenhang richtiger/logischer ... aus der Sichet eines Profis angebrachter?
Kommt drauf an[tm].
In deinem konkreten Fall würde ich die Begrenzer ^$ wohl weglassen. Aber sobald dein Suchmuster mal etwas komplexer ist als "alles was kommt" (.*), können die durchaus entscheidend sein.
Das Manual vom Apache ist leider nicht auf deutsch erhältlich im Moment.
Das ist schade. =(
Geschmackssache. Englischkenntnisse sind in der EDV ganz allgemein *sehr* empfehlenswert. Ich ziehe sogar englischsprachige Dokumentationen vor, selbst wenn es eine deutsche Fassung gibt.
Ciao,
Martin
Hi Martin,
Ich nehme an, du meinst das L, richtig? Also soll ich es streichen? Oder stehen lassen?
Stehenlassen, wenn weitere Regeln folgen, die in diesem Schritt nicht mehr relevant sind. Egal, wenn die Regel sowieso die letzte in der .htaccess ist.
Oder darf dieses [L] nur nach dem allerletzten mod_rewriting in der .htaccess stehen?
Genau dort ist es sinnlos.
ich bitte, mir das mit dem [L] näher zu erklären, ich verstehe es einfach nicht. Angenommen, ich habe in einer .htaccess 4 verschiedene mod_rewrite Anweisungen stehen. Ich habe verstanden, dass ich das "RewriteEngine on" nur ein mal schreiben muß. Aber was ist mit dem [L]? Kommt das jetzt jeweils in die letzte Zeile bei jedem Block, bis auf den letzten?
Und wenn ich nur _eine_ mod_rewrite Anweisung habe, dann kann ich es überhaupt weglassen?
MfG
Hugo E.B.
Hallo,
Oder darf dieses [L] nur nach dem allerletzten mod_rewriting in der .htaccess stehen?
Genau dort ist es sinnlos.
ich bitte, mir das mit dem [L] näher zu erklären, ich verstehe es einfach nicht.
hmm, was ist da so geheimnisvoll?
Angenommen, ich habe in einer .htaccess 4 verschiedene mod_rewrite Anweisungen stehen. Ich habe verstanden, dass ich das "RewriteEngine on" nur ein mal schreiben muß. Aber was ist mit dem [L]? Kommt das jetzt jeweils in die letzte Zeile bei jedem Block, bis auf den letzten?
Das [L]-Flag steht für "Last". Es bedeutet: Wenn diese Zeile zur Anwendung kommt, sollen für denselben Request keine weiteren Regeln mehr betrachtet werden. Lässt man das [L] weg, werden auch alle nachfolgenden RewriteRules noch bearbeitet, sofern deren Bedingung zutrifft. Es hängt also immer von der Logik ab, ob zwei oder mehr RewriteRules für denselben Request zutreffen könnten, und wenn ja, ob das erwünscht ist.
Und wenn ich nur _eine_ mod_rewrite Anweisung habe, dann kann ich es überhaupt weglassen?
Ja, denn dann ist es sinnlos. Eine einzelne RewriteRule ist automatisch immer die letzte. :-)
Ciao,
Martin
Hi Martin,
Das [L]-Flag steht für "Last". Es bedeutet: Wenn diese Zeile zur Anwendung kommt, sollen für denselben Request keine weiteren Regeln mehr betrachtet werden. Lässt man das [L] weg, werden auch alle nachfolgenden RewriteRules noch bearbeitet, sofern deren Bedingung zutrifft. Es hängt also immer von der Logik ab, ob zwei oder mehr RewriteRules für denselben Request zutreffen könnten, und wenn ja, ob das erwünscht ist.
Es tut mir leid, ich verstehe es noch immer nicht. Angenommen, es gibt in einer .htaccess 3 verschiedene mod_rewrite Bereiche. Der erste zB. zur Entfernung des 'www' beim Domainaufruf, dann ein Teil zum Schutz vor Fremdverlinkung und dann ein Teil der dafür zuständig ist, dass zB. beim Aufruf von www.example.com/blog?article=7364 ein www.example.com/blog daraus gemacht wird.
Diese 3 Dinger haben ja _nichts_ miteinander zu tun. Wird jetzt Teil 2 und 3 nicht ausgeführt, wenn ich zum Schluß der letzten Zeile des ersten Bereichs ein [L] schreibe? Dann würde ja das [L] nur nach dem 3. Teil einen Sinn machen, und das ist sinnlos, wurde mir schon erklärt. Na dann brauche ich es doch überhaupt nicht?!
MfG
Hugo E.B.