Hoe debug ik welke location nginx heeft gekozen?
Plak de config en de request-URI in deze tester om het winnende blok te zien en de reden waarom elk ander blok afviel. Op een draaiende server voeg je error_log /var/log/nginx/debug.log debug; toe en zoek je de regel "using configuration", die de geselecteerde location noemt. De twee aanpakken beantwoorden verschillende vragen: het log vertelt wat een live server heeft gedaan, en deze pagina vertelt wat een config die je nog niet hebt uitgerold zou doen.
Waarom werkt mijn nginx location-regex niet?
Meestal om een van drie redenen, en de beslissingstabel benoemt welke. Een eerdere regex matchte al, dus die van jou draaide nooit — regexen worden geprobeerd in bestandsvolgorde en de eerste match wint. Of de langste matchende prefix draagt ^~, waardoor de regexfase volledig wordt overgeslagen. Of de regex klopt maar de URI is niet wat je denkt: de matching draait tegen het genormaliseerde pad, na procent-decodering en het oplossen van .., met de query string eraf.
Waarom slaat mijn exacte match niet aan?
Een =-location vereist dat de hele URI gelijk is, niet dat die met het patroon begint. location = /a/ matcht /a niet, en location = /a matcht /a/b niet. Afsluitende slashes zijn hier gewone tekens, dus de twee vormen zijn verschillende strings. Matcht een exacte location wel, dan stopt het zoeken direct en wordt er verder niets meer vergeleken.
Matcht nginx de query string in een location-blok?
Nee. De query string wordt tijdens de normalisatie afgesplitst en de location-selectie draait alleen tegen het pad. Daarom matcht location = /a op een request naar /a?x=/b. Wil je vertakken op een parameter, dan moet je $arg_name of $args binnen het blok uitlezen. Eén subtiliteit is het waard om te kennen: %3F decodeert naar een letterlijk vraagteken dat in het pad blijft staan, dus /a%3Fx=1 heeft een lege query string en een pad met ? erin.
Kan ik JavaScript-regexsyntaxis gebruiken in een nginx location?
Nee — nginx gebruikt PCRE, en de verschillen doen ertoe. Deze pagina draait in je browser, waar alleen ECMAScript-reguliere expressies bestaan, dus PCRE-specifieke constructies worden gedetecteerd en gemarkeerd in plaats van stilzwijgend verkeerd geëvalueerd: atomic groups, possessive quantifiers, inline modifiers zoals (?i), POSIX-klassen zoals [[:alpha:]], en escapes als \A en \K die JavaScript geruisloos als gewone letters leest. Wordt een location gemarkeerd, dan worden de overige kandidaten nog steeds in de volgorde van nginx geëvalueerd, maar het oordeel over dat blok moet je op een echte server controleren. Schrijf je het patroon zelf, dan behandelt de regex-tester de ECMAScript-syntaxis uitgebreid. Zijn prefix-matches van nginx locations hoofdlettergevoelig?
Op Linux wel — location /Static/ matcht /static/x niet. Op niet-hoofdlettergevoelige bestandssystemen zoals macOS en Cygwin vergelijkt nginx prefixen hoofdletterongevoelig en dwingt het bovendien elke regex-location zich te gedragen als ~*. Deze pagina modelleert het Linux-gedrag, en dat is wat productieservers vrijwel altijd draaien. Ontwikkel je op een Mac en rol je uit naar Linux, dan kan dat verschil een kapotte regel verbergen tot hij live gaat.
Verandert try_files welk location-blok is geselecteerd?
Nee. De location-selectie is eerst klaar; try_files draait daarna, binnen het blok dat al gewonnen heeft. Bereikt een request nooit het blok met jouw try_files, dan is de directive irrelevant — de gebruikelijke oorzaak is een ~ \.php$-regex die het request pakt voordat het prefix-blok met de fallback aan bod komt. Een interne redirect die later wordt uitgestuurd start de matching wel opnieuw, dus een herschreven URI wordt weer vanaf de bovenkant tegen de location-lijst opgelost.
Waarom geeft nginx een 301 als ik een map zonder slash opvraag?
Daar zitten twee verschillende mechanismen achter. Draagt een location waarvan de naam op / eindigt een proxy_pass of een andere *_pass-directive, dan wordt een request naar hetzelfde pad zonder slash tijdens de location-selectie met een 301 beantwoord — voordat er ook maar één regex is geëvalueerd. Los daarvan geeft de module voor statische bestanden een 301 wanneer het pad naar een echte map op schijf verwijst. De eerste is hier zichtbaar; de tweede hangt van je bestandssysteem af. location = /path toevoegen onderdrukt de eerste.
Veranderen geneste location-blokken de uitkomst?
Ja, en op een manier die je makkelijk mist. nginx daalt af in de winnende prefix-location en doorzoekt de kinderen daarvan, dus een geneste regex wordt vóór de regexen van het bovenliggende niveau geprobeerd. Een ^~ op het buitenste blok schermt het niet af tegen zijn eigen geneste regexen, en nesting kan een globaal langere prefix onbereikbaar maken wanneer een broer op het buitenste niveau eerst wint. Geneste blokken worden hier gemodelleerd met dezelfde inspringing als waarmee je ze hebt geschreven.
Wordt mijn nginx-configuratie ergens geüpload?
Nee. Het parsen en matchen gebeurt lokaal in je browser met gewone stringbewerkingen — er is geen serveraanroep en er wordt niets bewaard. Dat weegt hier zwaarder dan bij de meeste tools, omdat een echt server-blok upstream-hostnames, interne poorten, certificaatpaden en authenticatieregels bevat. Je hoeft ons niet op ons woord te geloven: open de developer tools van je browser en kijk hoe het Network-paneel stil blijft terwijl je typt, of verbreek je verbinding helemaal en test door. Dat er geen enkel extern verzoek is, wordt bovendien bij elke build afgedwongen door een geautomatiseerde contracttest, dus het kan niet stilletjes terugvallen.