Cum funcționează try_files? (Administrarea sistemului, Nginx)

user274 a intrebat.

M-am uitat în documentația nginx și încă mă confundă complet.

Cum funcționează try_files funcționează? Iată ce scrie în documentație:

De la NginxHttpCoreModule

try_files

sintaxă: try_files path1 [path2] uri

implicit: none

context: server, location

disponibilitate: 0.7.27

Verifică existența fișierelor în ordine și returnează primul fișier care este găsit. O bară oblică la sfârșit indică un director – $uri /. În cazul în care nu se găsește niciun fișier, se invocă o redirecționare internă către ultimul parametru. Ultimul parametru este URI-ul de rezervă și trebuie să fie să existe, în caz contrar va fi generată o eroare internă. Spre deosebire de rewrite, $args nu sunt păstrate automat dacă fallback-ul nu este o locație numită. Dacă aveți nevoie de păstrarea arginților, trebuie să faceți acest lucru în mod explicit:

Nu înțeleg cum se verifică căile de acces și dacă nu doresc o eroare internă, ci să se reia restul căii de acces în încercarea de a găsi un alt fișier?

Dacă vreau să încerc un fișier memorat în cache la /path/app/cache/url/index.html și dacă nu reușește să încerce /path/app/index.php cum aș putea să scriu asta? Dacă aș scrie:

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;

Am index index.php index.html index.htm;. Când vizitez /urlname, , va încerca să verifice /path/app/cache/urlname/index.php apoi /path/app/cache/urlname/index.html? Dacă ignorăm totul după try_files este posibil ca try_files să se verifice dosarul cache? Am încercat și nu am reușit.

2 răspunsuri
Martin Fjordvald

try_files încearcă calea literală pe care o specificați în legătură cu directiva rădăcină definită și setează pointerul de fișier intern. Dacă utilizați, de exemplu try_files /app/cache/ $uri @fallback; cu index index.php index.html; atunci va testa căile de acces în această ordine:

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

înainte de a redirecționa în final la nivel intern către locația numită @fallback. De asemenea, puteți utiliza un fișier sau un cod de stare (=404) ca ultim parametru, dar dacă se folosește un fișier, se va folosi trebuie să existe.

Trebuie să rețineți că try_files nu va emite o redirecționare internă pentru nimic altceva decât pentru ultimul parametru. Ceea ce înseamnă că nu puteți face următoarele: try_files $uri /cache.php @fallback; deoarece acest lucru va face ca nginx să seteze pointerul de fișier intern la $document_root/cache.php și să îl servească, dar deoarece nu are loc nicio redirecționare internă, locațiile nu sunt reevaluate și, ca atare, va fi servit ca text simplu. (Motivul pentru care funcționează cu fișiere PHP ca index este că directiva index va fi emite o redirecționare internă)

Comentarii

  • Acest lucru este MULT mai clar. Vă mulțumim. Sunt puțin nesigur cum funcționează locația numită. Dacă @fallback are linii pentru fastcgi php care ar servi ca un fișier php mai degrabă decât ca text? Este fallback folosit atunci când tot ceea ce este înainte de el eșuează? – user274
  • O locație numită este identică din punct de vedere funcțional cu o locație normală, cu excepția faptului că poate fi accesată doar prin mecanisme interne, cum ar fi error_page și try_files. Fallback-ul din try_files este utilizat numai atunci când niciuna dintre căile specificate nu are ca rezultat un fișier valid. Aveți în continuare nevoie de o locație pentru a prinde URI-urile .php$, deoarece altfel try_files se va declanșa pe $uri dacă fișierul există și îl va servi ca text simplu. –  > Por Martin Fjordvald.
  • Mulțumesc pentru acest răspuns… Am totuși o întrebare: try_files este executat imediat sau locația imbricata va fi încercată înainte? –  > Por Stphane.
  • @Stphane Vă deplasați în ape tulburi aici. Moștenirea în nginx este complexă, dezordonată și complet inconsecventă. A trebuit să-mi revăd vechile note doar pentru a-mi aminti acest lucru, așa că nu vă garantez nimic, dar se pare că pentru try_files, în special atunci când se ocupă doar de locații imbricate, nu se va executa dacă locația interioară se potrivește. Aș recomanda să o testați, totuși. –  > Por Martin Fjordvald.
Craig Hicks

Iată o altă utilizare convenabilă a try_files, ca redirecționări necondiționate către locații numite. Locațiile numite acționează efectiv ca subrutine, economisind duplicarea codului. Atunci când primul argument pentru try_files este _ redirecționarea de rezervă este întotdeauna luată (presupunând că _ nu este un nume de fișier existent). Deoarece nginx are nevoie de un fișier goto statement dar nu are una.

    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;
    }

Comentarii

  • de fapt, tot ceea ce face acest lucru este să încerce fișierul _, , nu reușește, iar apoi folosește fallback-ul. Dacă creați fișierul _ în fișierul dvs. document_root, , toate aceste reguli vor eșua. –  > Por w00t.
  • @w00t – Acesta este un punct bun care necesită conștientizare. Ar fi util dacă Nginx ar avea o funcție goto declarație. –  > Por Craig Hicks.

Tags: