Wie funktioniert try_files?

72

Ich habe mir die Nginx-Dokumentation angesehen und es verwirrt mich immer noch zutiefst.

Wie funktioniert try_filesarbeiten? Folgendes steht in der Dokumentation:

Aus NginxHttpCoreModule

try_files

syntax: try_files pfad1 [pfad2] uri

Standardeinstellung: keine

Kontext: Server, Standort

Verfügbarkeit: 0.7.27

Überprüft, ob Dateien in der richtigen Reihenfolge vorhanden sind, und gibt die erste gefundene Datei zurück. Ein abschließender Schrägstrich kennzeichnet ein Verzeichnis - $ uri /. Wird keine Datei gefunden, wird eine interne Umleitung zum letzten Parameter aufgerufen. Der letzte Parameter ist der Fallback-URI und muss vorhanden sein. Andernfalls wird ein interner Fehler ausgelöst. Im Gegensatz zum Umschreiben werden $ args nicht automatisch beibehalten, wenn der Fallback kein benannter Speicherort ist. Wenn Sie Argumente beibehalten möchten, müssen Sie dies explizit tun:

Ich verstehe nicht, wie die Pfade überprüft werden und was ist, wenn ich keinen internen Fehler haben möchte, aber den Rest des Pfades wieder aufnehmen muss, um eine andere Datei zu finden?

Wenn ich eine zwischengespeicherte Datei unter /path/app/cache/url/index.htmlversuchen /path/app/index.phpmöchte und wenn es nicht versucht, wie würde ich das schreiben? Wenn ich schrieb:

try_files /path/app/cache/ $uri
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php-fastcgi/php-fastcgi.socket;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;

Ich habe index index.php index.html index.htm;. Wenn ich besuchen /urlname, werden versuchen, die Kontrolle /path/app/cache/urlname/index.phpdann /path/app/cache/urlname/index.html? Wenn wir alles danach ignorieren, try_filesist es dann möglich try_files, den Cache-Ordner zu überprüfen? Ich habe es versucht und bin gescheitert.

76484
quelle

Antworten:

64

try_files versucht den Literalpfad, den Sie in Bezug auf die definierte root-Direktive angegeben haben, und setzt den internen Dateizeiger. Wenn Sie zum Beispiel try_files /app/cache/ $uri @fallback;mit verwenden index index.php index.html;, werden die Pfade in dieser Reihenfolge getestet:

  1. $document_root/app/cache/index.php
  2. $document_root/app/cache/index.html
  3. $document_root$uri

bevor es schließlich intern zum benannten @fallback-Speicherort umgeleitet wird. Sie können auch eine Datei oder einen Statuscode ( =404) als letzten Parameter verwenden. Wenn Sie jedoch eine Datei verwenden, muss diese vorhanden sein .

Sie sollten beachten, dass try_files selbst nur für den letzten Parameter eine interne Umleitung ausgibt. Das heißt, Sie können Folgendes nicht tun: try_files $uri /cache.php @fallback;Dadurch setzt nginx den internen Dateizeiger auf $ document_root / cache.php und stellt ihn bereit. Da jedoch keine interne Umleitung stattfindet, werden die Speicherorte nicht erneut ausgewertet, und dies wird auch der Fall sein diente als einfacher Text. (Der Grund , es mit PHP - Dateien als Index funktioniert , ist , dass die Index - Richtlinie wird eine interne Umleitung Ausgabe)

Martin Fjordvald
quelle
2
Das ist VIEL klarer. Vielen Dank. Ich bin ein wenig unsicher, wie der genannte Ort funktioniert. Wenn @fallback Zeilen für FastCGI-PHP hat, die als PHP-Datei und nicht als Text dienen? Wird ein Fallback verwendet, wenn alles, bevor es fehlschlägt?
2
Ein benannter Speicherort ist funktional identisch mit einem normalen Speicherort, außer dass er nur über interne Mechanismen wie error_page und try_files zugänglich ist. Der Fallback in try_files wird nur verwendet, wenn keiner der angegebenen Pfade zu einer gültigen Datei führt. Sie benötigen weiterhin einen Speicherort, um \ .php $ URIs abzufangen, da sonst try_files auf $ uri ausgelöst wird, wenn die Datei vorhanden ist und als Nur-Text-Datei dient.
Martin Fjordvald
Vielen Dank für diese Antwort. Ich habe hier noch eine Frage: Wird try_files sofort ausgeführt, oder wird der verschachtelte Speicherort vorher getestet?
Stphane
@Stphane Du ziehst hier in trübe Gewässer. Vererbung in Nginx ist komplex, chaotisch und völlig inkonsistent. Ich musste meine alten Notizen überprüfen, um mich daran zu erinnern, daher gibt es keine Garantien, aber es scheint, dass try_files, insbesondere wenn es sich nur um verschachtelte Speicherorte handelt, nicht ausgeführt werden kann, wenn der innere Speicherort übereinstimmt. Ich würde jedoch empfehlen, es zu testen.
Martin Fjordvald
5

Hier ist eine weitere praktische Verwendung von try_files als bedingungslose Weiterleitung an benannte Speicherorte. Die benannten Speicherorte fungieren effektiv als Unterprogramme, wodurch eine Verdoppelung des Codes vermieden wird. Wenn das erste Argument für try_files "_" ist, wird immer die Fallback-Umleitung verwendet.

    location =/wp-login.php { try_files _ @adminlock; }
    location ^~ /wp-admin/  { try_files _ @adminlock; }
    location @adminlock  {
            allow 544.23.310.198;
            deny all;
            try_files _ @backend;
            # wp-admin traffic is tiny so ok to send all reqs to backend 
    }
    location ~ \.php {  try_files _ @backend; }
    location / { try_files $uri $uri/ =403; }
    location @backend {
            fastcgi_pass 127.0.0.1:9000;
            include snippets/fastcgi-php.conf;
    }
Craig Hicks
quelle