Nginx

有什麼區別你和我___在r一世一種nduri anduri/ 在 try_files 指令中?

  • February 21, 2022

這是配置:

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命令將返回 an HTTP 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.htmlhttp://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.htmlHTTP 404 Not Found將返回一個)。但是,由於內部 URI 由指令http://localhost/a/重寫,因此類似請求仍然可以使用。index``try_files $uri/ =404

引用自:https://serverfault.com/questions/1094254