Este exact $uri/
partea care face ca nginx să presupună că un URI poate fi un nume de director și să caute prezența unui fișier index în interiorul acestuia.
Să presupunem următoarea structură de directoare:
/var/www/html
âââ a
â âââ index.html
âââ b
â âââ index.html
â âââ index.htm
âââ c
â âââ test.html
...
și următoarea configurație nginx:
Server {
rădăcină /var/www/html;
index index.htm index.html;
Locație / {
try_files $uri $uri/ =404;
}
}
Iată ce s-a întâmplat cu următoarele răsuci
cereri:
-
curl http://localhost/a
Returnează o redirecționare:
HTTP/1.1 301 mutat permanent
Locație: http://localhost/a/
-
curl http://localhost/a/
Returnează /var/www/html/a/index.html
conținutul fișierului.
-
curl http://localhost/b
Returnează o redirecționare:
HTTP/1.1 301 mutat permanent
Locație: http://localhost/b/
-
curl http://localhost/b/
Returnează /var/www/html/b/index.htm
conținutul fișierului (existența fișierelor index este verificată în ordinea în care acestea sunt specificate utilizând fișierul index
directivă).
-
curl http://localhost/c
Returnează o redirecționare:
HTTP/1.1 301 mutat permanent
Locație: http://localhost/c/
-
curl http://localhost/c/
Deoarece nu există niciun fișier index în fișierul /var/www/html/c/
director, răsuci
comanda va returna un HTTP 403 Interzis
cu excepția cazului în care aveți un autoindex activat;
directivă din configurația dvs. (în acest caz, nginx va returna fișierul /var/www/html/c/
listare director).
Dacă configurația dvs. nginx va arăta ca
Server {
rădăcină /var/www/html;
index index.htm index.html;
Locație / {
try_files $uri =404;
}
}
fiecare dintre cererile de mai sus va returna acum un HTTP 404 nu a fost găsit
eroare. Un autoindex
directiva, dacă este prezentă, nu va avea niciun efect. Singura modalitate de a obține un index.html
conținutul va fi pentru a-l specifica în mod explicit, de ex. http://localhost/a/index.html
, http://localhost/b/index.htm
etc.
Lucrul foarte important, dar absolut neevident este că an index
directivă utilizată cu try_files $uri $uri/ =404
poate provoca o redirecționare internă. De exemplu, dacă veți avea următoarea configurație:
Server {
rădăcină /var/www/html;
index index.htm index.html;
Locație / {
add_header X-Test test1;
try_files $uri $uri/ =404;
}
locație /a/index.html {
add_header X-Test test2;
}
}
cerere http://localhost/a/
va provoca o redirecționare internă de la /A/
la /a/index.html
și returnați /var/www/html/a/index.html
conținutul fișierului cu personalizat X-Test
antet setat la test2
, nu să test1
!
Ultimul lucru care merită menționat este că try_files $uri $uri/ =404;
este comportamentul implicit nginx, deci
Locație / {
try_files $uri $uri/ =404;
}
și
Locație / {}
locațiile sunt total egale.
Actualizați
O întrebare suplimentară de la OP:
Gândurile mele au fost: $uri
examinează URI așa cum este și $uri/
examinează URI ca un director care caută un fișier index. Pentru http://localhost/a
cu try_files $uri /file.html =404;
eu iau fişier.html
. Bun pentru moment! Pentru http://localhost/a
cu try_files $uri/ /file.html =404;
eu iau fişier.html
de asemenea. De ce? Ma asteptam la index.html
. În plus, try_files $uri $uri/ /file.html =404;
îmi va aduce index.html
.
O intrebare foarte buna! Fără a răspunde, întregul răspuns va fi cumva incomplet. Să vedem ce se întâmplă aici.
Având http://localhost/a/
cerere și try_files $uri/ /file.html =404;
directivă din configurația dvs. nginx, la un prim pas, nginx a verificat /var/www/html/a/
directorul pentru a fi un director, apoi l-am verificat pentru prezența unui fișier index, am găsit un index.html
fișier în interiorul acestuia și a făcut o redirecționare internă de la /A/
la /a/index.html
. Într-o a doua etapă, fiind în interiorul aceluiași bloc de locație, nginx verifică /var/www/html/a/index.html
pentru că sunt un director, dar nu este! Și din moment ce nu ai un $uri
componentă ca a try_files
parametru directiv, merge pentru următoarea verificare pentru /var/www/html/file.html
fișier, l-a găsit și returnează conținutul său.
S-ar putea să credeți că folosind try_files
directivă fără an $uri
parametrul este complet inutil prin urmare. De obicei este, dar poate fi un caz de utilizare pentru a face acest lucru, de exemplu atunci când doriți să ascundeți structura internă a site-ului. Iată un exemplu:
Server {
rădăcină /var/www/html;
index index.html;
Locație / {
try_files $uri/ =404;
}
locație ~ /index\.html$ {
intern; # accesibil numai prin rescrierea URI internă
try_files $uri =404;
}
locație ~ \.(js|css|jpe?g|png)$ {
# serviți bunurile într-un mod obișnuit
try_files $uri =404;
}
}
Făcând asta locație ~ /index\.html$ { ... }
un intern, împiedicați accesul direct la dvs index.html
fișiere prin solicitări precum http://localhost/a/index.html
(un HTTP 404 nu a fost găsit
vor fi returnate în schimb). Cu toate acestea, solicitări ca http://localhost/a/
rămâne operabilă din cauza rescrierii URI interne de către index
directivă împreună cu try_files $uri/ =404
unu.