PHP Blogger

Startseite Schreib mir ne Mail! RSS Abo Webnews

mod_rewrite - Trailing Slash

Wir hören ja immer wieder, dass sich manchmal die Technologie hinter einer Webseite ändert und nichts wäre schlimmer, als die kostbaren Bookmarks unserer User, die wieder in die dritte Navigtionsstruktur deep-linken zu vergrämen, weil jetzt plötzlich die Seite login.php eben login.jsp heißt. Also ist es besser, wenn man die Extension direkt mal in die Tonne wirft und nur noch URLs nach dem Motto www.phpblogger.net/login hat. Noch besser und da streiten die Geister, sind Verzeichnisse. www.phpblogger.net/login/

Warum weiß ich nicht, aber ich wollte jedenfalls in meiner Applikation, dass es Verzeichnisse sind. Doch dann stellte ich fest, dass zum Beispiel der Internet Explorer in der Adress-History plötzlich den Trailing Slash vermissen ließ und ich damit aufgeschmissen wäre… Ihr fragt euch sicher, was das Problem ist, weil die meisten Webserver mittlerweile in einem solchen Fall nach einem Verzeichnis mit dem Namen suchen, wenn die Datei nicht gefunden wird, doch was ist wenn weder die Datei noch das Verzeichnis physikalisch auf dem Datenträger existieren?

Wie bei den meisten CMS gibt es bei mir auch nur eine zentrale Datei, die aufgerufen wird, nennen wir sie index.php. Also habe ich mit mod_rewrite jeden Verzeichnisaufruf nach /*/ nach index.php umgeleitet. Doch was ist jetzt, wenn jemand eben nur /* eingibt. Er bekommt erstmal einen 404-Fehler. Weil der Server findet ja weder die Datei noch ein entsprechendes Verzeichnis.

Nach einigem Suchen, fand man in der Apache Dokumentation nur eine Lösung, die bei existierenden Verzeichnissen umleitet. Also musste wohl eine Custom-Lösung her.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [L,R=301]

Die erste Cond checkt, ob es vielleicht doch eine exisitierende Datei (bsp. eine Bild-Datei) ist, die hier angefragt wird. Die zweite Cond checkt auf den fehlenden Slash am Ende und die Rule leitet um auf die entsprechende Seite und beendet das Rewriting. Die Suche hat mich ein halbes Jahr gedauert, bis ich endlich eine funktionsfähige Version hatte, vorher wurde ich jedes Mal wieder von den 500-Server-Errors gebremst.

Dazu noch einen Tipp, den ich auch erst kürzlich in dem Zusammenhang gelernt habe:

RewriteEngine On
RewriteLog "pfad/logs/rewrite.log"
RewriteLogLevel 9

hilft ungemeint. Damit schreibt der Apache nämlich ein genaues Logfile über sein rewrite Verhalten und warum er jetzt was ersetzt und was er ersetzt.

Duddle meint dazu:

18. Juni 2007 um 09:00

Ein Logging für Rewrites! Danke, danke, danke :-) Man lernt nur dazu…

Frank meint dazu:

12. Juli 2007 um 15:37

Ich mache es folgendermaßen:
RewriteCond %{REQUEST_URI} ^/[^\.]+[^/]$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [R=301,L]

Welches ist die bessere Lösung?

phil meint dazu:

12. Juli 2007 um 16:59

Das Problem was ich mit deiner Lösung hätte, ist, dass ich Dateien, die existieren und die damit keinen Trailingslash benötigen nicht abfange. Ich möchte ja gerade, dass z.B. ./style/content.css auch als .css geladen wird und nicht einen Rewrite auf content.css/ bekommt. Oder kannst du es erzwingen, dass alle Links, die intern sind, immer mit ./ oder mit / anfangen, was du ja dann abfängst?

Ich benutze das halt in einem CMS und bin dann irgendwann mal nicht mehr der einzige, der da Links setzt und das andere ist halt dann auch ein korrekter Link, oder?

Frank meint dazu:

13. Juli 2007 um 07:51

OK, richtig - dann habe ich es nun verstanden. Danke nochmal für die Antwort. Bei meiner Lösung wird im / angefügt, was natürlich für reale Dateien schlecht wäre.

Frank meint dazu:

13. Juli 2007 um 07:58

Habe das nochmal mit meinen Einstellungen geprüft, es werden alle Dateien, die sich als Link oder in einem Verzeichnis befinden, auch so geladen, also es wird z.B. /theme/new/style.css als .css geladen, gleiches gilt für .phps.

phil meint dazu:

13. Juli 2007 um 14:51

Oh ok, du überprüfst noch, ob die URL keinen Punkt enthält… mit dem [^\.] vermute ich… Dann dürfte es bei Verzeichnissen, die einen “.” enthalten nicht funktionieren, was aber auch eher eine seltene Anwendung ist, aber manchmal laden die Leute halt sowas wie “Bilder_vom_30.06.07″ hoch… Das dürfte dann nicht mehr funktionieren… Aber das ist auch gerade mehr eine Vermutung, also kann man sagen, dass beide Versionen durchaus funktionieren dürften ;)

Willi meint dazu:

24. Oktober 2007 um 04:06

Hab ich schon erwähnt dass ich Leute, die ihre Erfahrungen Anderen mitteilen, verdammt gut leiden kann? Dafür gibts 100 Punkte von mir. Wenn ich mal im Lotto gewinne, bekommst du mit Sicherheit was ab :) Gesucht, gefunden!

dunkelfuerst meint dazu:

9. September 2008 um 17:10

verdammt, ich liebe dich :D

Sebastian meint dazu:

15. Oktober 2008 um 11:06

Hab mich auch schon totgesucht, deine Lösung klappt auch prima!
Aber: wenn eine Datei mal nicht existiert (www.beispiel.de/gibts-nicht.html), dann wird vor der 404-Seite noch ein Trailing-Slash angehängt (www.beispiel.de/gibts-nicht.html/).
Mutet für den Suchenden vielleicht ein bisschen seltsam an… kriegt man das irgendwie weg?

phil meint dazu:

15. Oktober 2008 um 17:49

Hallo Sebastian,

das ist ja eigentlich genau die Idee dieses Rewrite, dass für Seiten, die es nicht gibt, ein ‘/’ angehängt wird. Vielleicht beschreibst du noch mal etwas genauer was du damit vorhast. Ist es so, dass du verschiedene Verzeichnisse (bsp. /kontakt/) hast und wenn jemand nur ‘/kontakt’ eingibt, dann soll der slash angehängt werden? Dann könntest du einfach probieren, noch eine RewriteCond einzufügen, die verhindert, dass die Rule auf Dateien, die bsp. in .html enden angewendet wird.

Ali meint dazu:

9. November 2009 um 02:22

DANKE für die Lösung.
Du hast mir damit mindestens einige Tage suchen abgenommen und es ist genau das was ich brauche.

Tina meint dazu:

21. März 2010 um 22:07

Super, ich danke dir. Der Tipp ist auch nützlich, damit Google Webmastertools, die Links nicht doppelt crawlt. Z.B. bei mir werden alle links umgeschrieben, so zum Beispiel wird aud http://www.domain.de/index.php?id=1&cat=impressum, der Link http://www.domain.de/impressum. Soweit ok, aber ohne deinen Zusatz finden man die Seite auch über http://www.domain.de/impressum/ … Ich hätte lieber nur die Eine Variante und dabei hat mir dein Blogeintrag wunderbar geholfen.
Danke :)

bmueller meint dazu:

24. August 2010 um 10:59

Moin,

Danke für deinen Lösungsansatz, konnte damit mein Trailing Slash Problem lösen.
Habe noch einige Modifizierungs vorschläge zu deiner Version

zuerst prüfen ob ein Slash vorhanden ist ((.*) wird dazu nicht benötigt), da wenn ein Slash vorhanden ist die Prüfung im Dateisystem wechfällt.

RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+[^/])$ $1/ [L,R=301]

Wenn man mod_rwrite zum erzeugen von *.html Links verwendet muss dazu noch ein Prüfung auf den Punkt eingebaut werden da diese ja nicht im Dateisystem sind und somit mit einem Slash versehen werden, vorrausgesetzt man verwenet keine Punkte in Verzeichnissnamen.

RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} ![\.]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+[^/])$ $1/ [L,R=301]

Dadruch kann man jetzt auch die Prüfung im Dateisystem wechlassen, was ne menge Performance spart.

Also kurz, kein Slash am ende und kein Punkt drinne == Umleiten

RewriteCond %{REQUEST_URI} !/$
RewriteCond %{REQUEST_URI} ![\.]
RewriteRule ^(.+[^/])$ $1/ [L,R=301]

MfG

bmueller meint dazu:

24. August 2010 um 11:07

Was ich noch vergessen habe man kann auch mit dem Apache Modul mod_dir den Trailing Slash setzten lassen. Aber nur bei statischen URL.

Chat-Thread - Seite 1764 - XHTMLforum meint dazu:

13. Mai 2011 um 18:18

[...] trailing slash: PHP Blogger: mod_rewrite - Trailing Slash - Ein PHP Blog auf deutsch Add Trailing Slash to the End of the URL with .htaccess Rewrite Rules

RSS für Kommentare zu diesem Artikel · TrackBack URI

Schreib Deine Meinung