RewriteCond seltsames Verhalten (Datei vorhanden ist-Prüfung)
Ich kann nicht verstehen, warum umleiten, hängt davon ab, RewriteRule (nicht auf RewriteCond).
Meine .htaccess:
Options +FollowSymLinks +SymLinksIfOwnerMatch
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*)$ true.txt
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ false.txt
</IfModule>
Root-Ordner enthält:
true.txt (enthält "true")
falsch.txt (enthält "false")
test.txt (enthält 'test')
Wenn ich versuche zu öffnen test.txt
bekomme ich true
und wenn ich versuche zu öffnen nonexist.txt
bekomme ich true
zu.
Nun ich mein .htaccess:
...
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*)$ $1
...
Und jetzt wenn ich versuche zu öffnen test.txt
bekomme ich test
und wenn ich versuche zu öffnen nonexist.txt
bekomme ich false
.
UPDATE: vielen Dank für die Antworten, ich habe verstanden, wie es funktioniert, aber ein problem besteht immer noch.
Wenn ich versuchen, zu prüfen, 'wenn Datei existiert' in einem anderen Verzeichnis, es gibt immer false
.
/files/test.txt
/script/.htaccess
/script/false.txt
/script/true.txt
nun meine .htaccess sieht wie
RewriteCond %{REQUEST_FILENAME} .*(true|false).*$
RewriteRule .* - [S=2]
RewriteCond %{DOCUMENT_ROOT}/files/%{REQUEST_FILENAME} -f
RewriteRule ^(.*)$ true.txt [L]
RewriteCond %{DOCUMENT_ROOT}/files/%{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ false.txt [L]
Bekomme ich immer false
.
Ich habe auch versucht RewriteCond ../files/%{REQUEST_FILENAME}
und auch immer false
Ergebnis.
Wenn ich mich bewege test.txt
im script
Ordner und ändern Sie dann RewriteCond %{REQUEST_FILENAME}
alle funktioniert.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist wegen der Art, wie mod_rewrite funktioniert: der Benutzer fordert test.txt, mod_rewrite fängt die Anfragen und umschreiben der URI zu false.txt, dann macht es einen zweiten Durchgang, indem Sie eine interne Anfrage für false.txt, welche gefangen und umgeschrieben true.txt. Dann ein Dritter Durchgang ist gemacht, die Anfrage abgefangen und umgeschrieben, um true.txt aber da die URI gleich bleibt, nicht mehr geht gemacht werden.
Es ist eher counter-intuitive, aber es ist Logik. Hier ist die control-flow-Diagramm aus der docs:
Dem [L] flag wird oft angepriesen als eine Magische Kugel zu stoppen die Rekursion, sondern in der Tat nur sichergestellt, dass, sobald eine Anfrage einem Muster entspricht, dann wird die Ausführung beendet und keine weitere Verarbeitung stattfinden wird in den pass, aber die interne Anforderung wird gesendet werden, jedenfalls, so einen zweiten Durchgang durch den gleichen Regelsatz. Die Ausführung Stoppt nur, wenn die URI ist unverändert nach einem pass.
re: update
Dein problem ist, das REQUEST_FILENAME Umwelt-variable, die tatsächlich hält ein Pfad (standardmäßig ist der vollständige Pfad im Dateisystem, aber es gibt ein paar Wendungen auf, dass), also %{DOCUMENT_ROOT}/files/%{REQUEST_FILENAME} endet als etwas schreckliches.
Als für eine Lösung... naja, es ist heikel, denke ich. Es wäre viel einfacher, wenn die .htaccess wurden in root. Die einzige Lösung, die ich denken kann ist im Moment:
Es ist ziemlich hässlich und nicht sehr skalierbar oder tragbar. In der ersten Bedingung bekomme ich den Dateinamen, in der zweiten ich überprüfen, ob es existiert, und wenn es tut, es ist wahr. Alles andere ist falsch. Dann wieder, wenn die Dateien-Verzeichnis ist ebenfalls in den Anwendungsbereich der .htaccess, ist es einfacher und schöner von Größen.
Hinweis: die zweite
RewriteCond
um zu verhindern, dass das umschreiben true.txt und false.txt Dateien undL
Flagge an die Regeln zu stop-Regeln, AusführungDiese werden um zu verhindern, dass Regeln loop
UPDATE:
%{REQUEST_FILENAME}
ist voll Weg, daher, wenn Sie fügen Sie es zu einem Weg, erhalten Sie false (es werden versuchen, entsprechen diese im wesentlichen:/var/www/subfolder/var/www/filename.txt
Passt Datei in einem anderen Ordner benötigen Sie ein match vs URI-Teil...
Hier ist, wie Sie es tun können:
%1
(ergänzt durch erste Bedingung) existiert im Unterordnerfiles/
innen%{DOCUMENT_ROOT}
Statt mit "RewriteCond %{REQUEST_FILENAME} !-f" können Sie Folgendes ausprobieren:
"RewriteCond %{THE_REQUEST} !-U", die überprüft, ob die Adresse existiert.
Manchmal wird der Pfad der Datei und die Adresse, wo die Datei ist serviert, sind anders, machen die ehemaligen unbrauchbar.
Beispiel: