有什麼區別你和我___在r一世一種nduri anduri/ 在 try_files 指令中?
這是配置:
index index.html; location / { try_files $uri $uri/ = 404; }
我在 http://localhost/path/a/ 發出請求。我假設這是 URI,因此在 $uri 階段 try_files 將查看 /path/a/ 並提供 index.html(如果有)。
我從文件中讀到,
It is possible to check directory’s existence by specifying a slash at the end of a name, e.g. “$uri/”.
但這對我來說沒有任何意義。
這正是
$uri/
使 nginx 假設 URI 可以是目錄名並在其中查找索引文件存在的部分。假設以下目錄結構:
/var/www/html ├── a │ └── index.html ├── b │ ├── index.html │ └── index.htm ├── c │ └── test.html ...
和以下 nginx 配置:
server { root /var/www/html; index index.htm index.html; location / { try_files $uri $uri/ =404; } }
curl
以下是以下請求發生的情況:
curl http://localhost/a
返回重定向:
HTTP/1.1 301 Moved Permanently Location: http://localhost/a/
* ``` curl http://localhost/a/
返回
/var/www/html/a/index.html
文件內容。
curl http://localhost/b
返回重定向:
HTTP/1.1 301 Moved Permanently Location: http://localhost/b/
* ``` curl http://localhost/b/
返回
/var/www/html/b/index.htm
文件內容(索引文件是否存在按照使用index
指令指定的順序進行檢查)。
curl http://localhost/c
返回重定向:
HTTP/1.1 301 Moved Permanently Location: http://localhost/c/
* ``` curl http://localhost/c/
/var/www/html/c/
由於目錄中沒有索引文件,因此curl
命令將返回 anHTTP 403 Forbidden
,除非您autoindex on;
的配置中有指令(在這種情況下,nginx 將返回/var/www/html/c/
目錄列表)。如果你的 nginx 配置看起來像
server { root /var/www/html; index index.htm index.html; location / { try_files $uri =404; } }
現在,上述每個請求都將返回
HTTP 404 Not Found
錯誤。指令,如果autoindex
存在,將無效。獲取index.html
內容的唯一方法是明確指定它,例如http://localhost/a/index.html
等http://localhost/b/index.htm
。非常重要但絕對不明顯的事情是,
index
正在使用的指令try_files $uri $uri/ =404
可能會導致內部重定向。例如,如果您將具有以下配置:server { root /var/www/html; index index.htm index.html; location / { add_header X-Test test1; try_files $uri $uri/ =404; } location /a/index.html { add_header X-Test test2; } }
請求
http://localhost/a/
將導致內部重定向 from/a/
to/a/index.html
並返回自定義標頭設置為的/var/www/html/a/index.html
文件內容,而不是!X-Test``test2``test1
最後值得一提的是
try_files $uri $uri/ =404;
預設的 nginx 行為,所以location / { try_files $uri $uri/ =404; }
和
location / {}
位置完全相等。
更新
OP的另一個問題:
我的想法是:
$uri
按原樣檢查 URI,並將$uri/
URI 作為查找索引文件的目錄進行檢查。因為我http://localhost/a
得到. 現在好!因為我也得到了。為什麼?我期待著。此外,會給我.try_files $uri /file.html =404;``file.html``http://localhost/a``try_files $uri/ /file.html =404;``file.html``index.html``try_files $uri $uri/ /file.html =404;``index.html
一個非常好的問題!如果不回答它,整個答案將是不完整的。讓我們看看這裡發生了什麼。
在您的 nginx 配置中擁有
http://localhost/a/
請求和try_files $uri/ /file.html =404;
指令,第一步 nginx 檢查/var/www/html/a/
目錄是否為目錄,接下來檢查它是否存在索引文件,在其中找到一個文件並從toindex.html
進行內部重定向。第二步,在同一個位置塊內,nginx 檢查是否是一個目錄,但它不是!而且由於您沒有將組件作為指令參數,因此它會進行下一次檢查文件,找到它並返回其內容。/a/``/a/index.html``/var/www/html/a/index.html``$uri``try_files``/var/www/html/file.html
因此,您可能認為使用
try_files
不帶參數的指令$uri
是完全沒用的。通常是這樣,但它可能是一個案例,例如當您想要隱藏內部站點結構時。這是一個例子:server { root /var/www/html; index index.html; location / { try_files $uri/ =404; } location ~ /index\.html$ { internal; # only accessible via internal URI rewrite try_files $uri =404; } location ~ \.(js|css|jpe?g|png)$ { # serve the assets in a usual way try_files $uri =404; } }
將其
location ~ /index\.html$ { ... }
設為內部,您可以防止index.html
通過請求直接訪問您的文件,例如http://localhost/a/index.html
(HTTP 404 Not Found
將返回一個)。但是,由於內部 URI 由指令http://localhost/a/
重寫,因此類似請求仍然可以使用。index``try_files $uri/ =404