Wie finde ich heraus, welche location nginx ausgewählt hat?
Fügen Sie die Konfiguration und die Anfrage-URI in diesen Tester ein, um den gewinnenden Block zu sehen und zu erfahren, warum jeder andere Block ausgeschieden ist. Auf einem laufenden Server ergänzen Sie error_log /var/log/nginx/debug.log debug; und suchen die Zeile "using configuration", die die ausgewählte location nennt. Die beiden Wege beantworten unterschiedliche Fragen: Das Log sagt Ihnen, was ein laufender Server getan hat, diese Seite sagt Ihnen, was eine noch nicht ausgerollte Konfiguration tun würde.
Warum funktioniert mein nginx location-Regex nicht?
Meist ist es einer von drei Gründen, und die Entscheidungstabelle benennt, welcher. Ein früherer regulärer Ausdruck hat bereits gepasst, Ihrer wurde also nie ausgeführt — reguläre Ausdrücke werden in Dateireihenfolge geprüft, der erste Treffer gewinnt. Oder das längste passende Präfix trägt ^~, was die Regex-Phase komplett überspringt. Oder der Ausdruck ist in Ordnung, aber die URI ist nicht die, die Sie erwarten: Gematcht wird gegen den normalisierten Pfad, nach Prozent-Dekodierung und Auflösung von .., ohne Query-String.
Warum greift mein exakter Treffer nicht?
Eine =-location verlangt, dass die gesamte URI gleich ist, nicht dass sie mit dem Muster beginnt. location = /a/ passt nicht auf /a, und location = /a passt nicht auf /a/b. Abschließende Schrägstriche sind hier ganz gewöhnliche Zeichen, die beiden Formen sind also verschiedene Zeichenketten. Passt eine exakte location, endet die Suche sofort und nichts anderes wird überhaupt noch verglichen.
Matcht nginx den Query-String in einem location-Block?
Nein. Der Query-String wird bei der Normalisierung abgetrennt, und die Auswahl der location läuft allein gegen den Pfad. Deshalb passt location = /a auf eine Anfrage nach /a?x=/b. Wenn Sie anhand eines Parameters verzweigen müssen, lesen Sie im Block $arg_name oder $args. Eine Feinheit lohnt sich zu wissen: %3F wird zu einem literalen Fragezeichen, das im Pfad bleibt, /a%3Fx=1 hat also einen leeren Query-String und einen Pfad, der ein ? enthält.
Kann ich JavaScript-Regex-Syntax in einer nginx location verwenden?
Nein — nginx nutzt PCRE, und die Unterschiede sind relevant. Diese Seite läuft in Ihrem Browser, wo es nur ECMAScript-Ausdrücke gibt; PCRE-eigene Konstrukte werden deshalb erkannt und markiert, statt stillschweigend falsch ausgewertet zu werden: atomare Gruppen, possessive Quantoren, Inline-Modifikatoren wie (?i), POSIX-Klassen wie [[:alpha:]] und Escapes wie \A und \K, die JavaScript klaglos als gewöhnliche Buchstaben liest. Ist eine location markiert, werden die übrigen Kandidaten weiterhin in nginx' Reihenfolge ausgewertet, aber das Urteil zu diesem Block gehört auf einem echten Server geprüft. Wenn Sie das Muster selbst schreiben, deckt der Regex-Tester die ECMAScript-Syntax ausführlich ab. Unterscheiden nginx location-Präfixe Groß- und Kleinschreibung?
Unter Linux ja — location /Static/ passt nicht auf /static/x. Auf Dateisystemen ohne diese Unterscheidung, etwa unter macOS und Cygwin, vergleicht nginx Präfixe ohne Beachtung der Groß-/Kleinschreibung und zwingt zusätzlich jede Regex-location, sich wie ~* zu verhalten. Diese Seite bildet das Linux-Verhalten ab, das auf Produktionsservern praktisch immer gilt. Wer auf einem Mac entwickelt und auf Linux ausrollt, übersieht durch diesen Unterschied eine kaputte Regel leicht bis ins Deployment.
Ändert try_files, welcher location-Block ausgewählt wurde?
Nein. Die Auswahl der location ist zuerst abgeschlossen; try_files läuft danach, innerhalb des Blocks, der bereits gewonnen hat. Erreicht eine Anfrage den Block mit Ihrem try_files nie, ist die Direktive belanglos — üblicher Grund ist ein ~ \.php$-Regex, der die Anfrage abfängt, bevor der Präfix-Block mit dem Fallback überhaupt zum Zug kommt. Ein später ausgelöster interner Redirect startet das Matching allerdings neu, eine umgeschriebene URI wird also erneut von oben gegen die location-Liste aufgelöst.
Warum antwortet nginx mit 301, wenn ich ein Verzeichnis ohne Schrägstrich anfrage?
Dafür gibt es zwei verschiedene Mechanismen. Trägt eine location, deren Name auf / endet, ein proxy_pass oder eine andere *_pass-Direktive, wird eine Anfrage auf denselben Pfad ohne Schrägstrich schon während der location-Auswahl mit 301 beantwortet — bevor irgendein regulärer Ausdruck ausgewertet wird. Davon unabhängig sendet das Modul für statische Dateien ein 301, wenn der Pfad auf ein echtes Verzeichnis auf der Platte zeigt. Das Erste ist hier sichtbar, das Zweite hängt von Ihrem Dateisystem ab. Ein zusätzliches location = /path unterdrückt das Erste.
Ändern verschachtelte location-Blöcke das Ergebnis?
Ja, und zwar auf eine Art, die man leicht übersieht. nginx steigt in die gewinnende Präfix-location hinab und durchsucht deren Kinder, ein verschachtelter regulärer Ausdruck wird also vor den regulären Ausdrücken der Elternebene geprüft. Ein ^~ am äußeren Block schützt ihn nicht vor seinen eigenen verschachtelten regulären Ausdrücken, und Verschachtelung kann ein insgesamt längeres Präfix unerreichbar machen, wenn ein Geschwisterblock auf der äußeren Ebene zuerst gewinnt. Verschachtelte Blöcke werden hier mit derselben Einrückung abgebildet, in der Sie sie geschrieben haben.
Wird meine nginx-Konfiguration irgendwohin hochgeladen?
Nein. Parsen und Matchen passieren lokal in Ihrem Browser mit einfachen Zeichenketten-Operationen — es gibt keinen Server-Aufruf und nichts wird gespeichert. Das wiegt hier schwerer als bei den meisten Tools, weil ein echter server-Block Upstream-Hostnamen, interne Ports, Zertifikatspfade und Auth-Regeln enthält. Sie müssen uns das nicht glauben: Öffnen Sie die Entwicklerwerkzeuge Ihres Browsers und sehen Sie zu, wie das Netzwerk-Panel beim Tippen stumm bleibt, oder trennen Sie die Verbindung ganz und testen Sie weiter. Dass keine externe Anfrage stattfindet, wird zusätzlich bei jedem Build durch einen automatisierten Vertragstest erzwungen und kann daher nicht unbemerkt zurückfallen.