Rewrite Spiele mit Apache
Das Ziel: Existierende Dateien werden normal angezeigt. Bei nicht existierenden Dateien wird statt Error 404 der Erfolgsstatus 200 und ein Standard-Dokument ausgegeben.
Klingt einfach? Ist es nicht. Das liegt primär daran, dass dafür mod_rewrite braucht, wofür keine gescheite Dokumentation existiert (ist ja schön, wenn die offizielle Doku alle verfügbaren Variablen auflistet, sie aber nirgends erklärt...) und alle bestehenden Howtos irgendwo einen Fehler machen oder diesen zugegebenermassen sehr speziellen Fall überspringen.
So scheitern praktisch alles bestehenden Vorschläge an der fehlerhaften RewriteCond:
-d und -f prüfen aber den absoluten Dateisystempfad, während REQUEST_FILENAME nur den Teil enthält, welcher in der URL nach dem Hostname steht, d.h. http://www.example.com/requested/filename.html. Somit werden diese Rewrite Conditions sowieso niemals zutreffen. Nun gibt es zwei Lösungen dafür. Entweder den ausschliessenden Weg, dass man alle existierenden Dateien von Hand explizit spezifiziert, z.B.
Nur hat dies zwei Nachteile, es ist aufwändig und unflexibel. Na gut, die simplere Lösung ist es den vorangehenden Pfadnamen hinzuzufügen, dafür gibt es die glücklicherweise vom Namen her sprechende DOCUMENT_ROOT Variable (eine offizielle Dokumentation, wo diese beschrieben wird, ist aus irgendwelchen Gründen schwierig zu finden...), so dass eine funktionierende, flexible und universelle Regel etwa so aussehen könnte:
Klingt einfach? Ist es nicht. Das liegt primär daran, dass dafür mod_rewrite braucht, wofür keine gescheite Dokumentation existiert (ist ja schön, wenn die offizielle Doku alle verfügbaren Variablen auflistet, sie aber nirgends erklärt...) und alle bestehenden Howtos irgendwo einen Fehler machen oder diesen zugegebenermassen sehr speziellen Fall überspringen.
So scheitern praktisch alles bestehenden Vorschläge an der fehlerhaften RewriteCond:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
-d und -f prüfen aber den absoluten Dateisystempfad, während REQUEST_FILENAME nur den Teil enthält, welcher in der URL nach dem Hostname steht, d.h. http://www.example.com/requested/filename.html. Somit werden diese Rewrite Conditions sowieso niemals zutreffen. Nun gibt es zwei Lösungen dafür. Entweder den ausschliessenden Weg, dass man alle existierenden Dateien von Hand explizit spezifiziert, z.B.
RewriteCond %{REQUEST_FILENAME} !^/robots.txt$
RewriteCond %{REQUEST_FILENAME} !^/favicon.ico$
Nur hat dies zwei Nachteile, es ist aufwändig und unflexibel. Na gut, die simplere Lösung ist es den vorangehenden Pfadnamen hinzuzufügen, dafür gibt es die glücklicherweise vom Namen her sprechende DOCUMENT_ROOT Variable (eine offizielle Dokumentation, wo diese beschrieben wird, ist aus irgendwelchen Gründen schwierig zu finden...), so dass eine funktionierende, flexible und universelle Regel etwa so aussehen könnte:
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteRule ^.+$ /index.html [L]