下面這個解答是來自于 ChatGPT,在后面我添加了一些案例和測試過程
Root 和 Alias 是 nginx 中用于設(shè)置文件路徑的兩個指令,它們在使用場景和效果上有一些區(qū)別:
- root指令:
root指令用于定義請求的根目錄。在一個 server 塊中,它定義了所有請求的根目錄。- 當請求到達時,nginx 會將 URI 添加到
root指定的路徑上,以確定請求的實際文件路徑。- 例如,如果
root /usr/share/nginx/html;設(shè)置在server塊中,那么對于 URI/index.html,nginx 將嘗試在/usr/share/nginx/html/index.html中查找文件。- alias指令:
alias指令用于為指定的 URI 創(chuàng)建一個別名路徑,它允許將請求的 URI 與文件系統(tǒng)中的實際路徑解耦。- 當請求到達時,nginx 會將 URI 替換為
alias指定的路徑,然后查找文件。- 例如,
alias /data/;可以將 URI/data/index.html映射到/data/index.html。在你的配置中,
root指令用于定義所有請求的根目錄,而alias指令用于為/data/URI 創(chuàng)建一個別名路徑。這意味著對于/data/下的請求,nginx 將使用alias指令提供的路徑,而不是將 URI 添加到root指定的路徑上。
如果看起來似乎還是有點不太理解,我來再進行解答一次。如果還不理解,在后面還有我測試的一些記錄
聲明:以下內(nèi)容僅是我個人的理解,若有解答的不全或解答錯誤,還望補充與教導(dǎo),謝謝
-
root 指令
-
root指令用于定義請求的根目錄。在一個 server 塊中,它定義了所有請求的根目錄。這個應(yīng)該好理解 - 當請求到達時,nginx 會將 URI 添加到
root指定的路徑上,以確定請求的實際文件路徑。(注意看黑體的地方)
例子1:如果
root /usr/share/nginx/html;設(shè)置在server塊中,那么對于 URI/index.html,nginx 將嘗試在/usr/share/nginx/html/index.html中查找文件。只看上面一個例子,可能還是不好理解,那我再加一些例子增加助于理解
-
例子2:
location /data2/ { root /usr/share/nginx/html/; autoindex on; }如果是上面這種配置。那么對于 URI
/data2/app/index.html,nginx將嘗試在/usr/share/nginx/html/data2/app/index.html中查找文件
通過上面的三個例子,可以在最后得出結(jié)論:
當配置為 root ,請求到達時。nginx 會將請求的路徑拼接到 root 后面,也就是說會將你配置的 root 作為根節(jié)點
-
alias 指令
-
alias指令用于為指定的 URI 創(chuàng)建一個別名路徑,它允許將請求的 URI 與文件系統(tǒng)中的實際路徑解耦。 - 當請求到達時,nginx 會將 URI 替換為
alias指定的路徑,然后查找文件。
例子1:
alias /data/;可以將 URI/data/index.html映射到/data/index.html。例子2:
location /data2/ { alias /usr/share/nginx/html/; autoindex on; }如這種配置。那么對于 URI
/data2/app/index.html,nginx將會使用/usr/share/nginx/html/替換掉/data2/然后再查找文件。替換后的路徑為/usr/share/nginx/html/app/index.html -
結(jié)論
- 配置為 root 時,nginx 會將到達的請求,拼接到配置的 root 路徑后方
- 配置為 alias 時,nginx 會將到達的請求,替換為 alias 后配置的路徑
接下來我通過一個實際的例子以及日志來解答這個問題
root
配置如下,重點關(guān)注配置文件中的 location /data/ 部分
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location /data/ {
root /data/;
autoindex on;
}
}
代理的目錄結(jié)構(gòu)
我在 data 目錄下有兩個文件,文件名和內(nèi)容都不重要
-- data
---- sitemap.xml
---- robots.txt
現(xiàn)在我使用的是 root 的方式配置的。
當我使用 http://localhost/data/sitemap.xml 去訪問頁面的時候,按我的慣有思維,應(yīng)該是這么理解的
- 首先nginx解析到 /data/ 路徑,
- 根據(jù) /data/ 的配置找到 root 這個配置路徑
- 根據(jù) sitemap.xml 這個文件。從 root 配置的這個路徑后去取實際的這個文件
但是我得到的結(jié)果卻是 404
接下來我看 nginx 的日志文件,在 /var/log/nginx/error.log 中會有下面這個日志
2024/04/25 03:31:17 [error] 23#23: *2 open() "/data/data/sitemap.xml" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /data/sitemap.xml HTTP/1.1", host: "127.0.0.1"
可以從日志中看出來,nginx 實際在處理的時候多拼接了一個 data 的路徑
這時候就有人想,如果我使用 http://localhost/sitemap.xml 這個去掉 data 的路徑訪問不就可以了。
但是這時候由于你沒有加上 /data/ 這個路徑,ngxin 實際就會觸發(fā)下面的這個規(guī)則
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
你就會得到下面的這個錯誤日志
2024/04/25 03:32:43 [error] 24#24: *3 open() "/usr/share/nginx/html/sitemap.xml" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /sitemap.xml HTTP/1.1", host: "127.0.0.1"
所以這個辦法是行不通的
解決思路
提出疑問:既然他變成了 /data/data/sitemap.xml 這個路徑了??雌饋硎遣皇怯悬c像是把我請求的路徑給拼接到了 root 中配置的路徑的后面?
實驗一下。修改配置文件
location /data2/ {
root /data/;
autoindex on;
}
現(xiàn)在我使用新的連接訪問看得到的是什么樣的結(jié)果
http://localhost/data2/sitemap.xml
可以得到下面的這個錯誤日志
2024/04/25 03:31:17 [error] 23#23: *2 open() "/data/data2/sitemap.xml" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /data2/sitemap.xml HTTP/1.1", host: "127.0.0.1"
根據(jù)日志,印證了我的猜想。
當我用下面這種帶有路徑的規(guī)則時。Nginx 會將我 URL 中的路徑拼接到配置的 root 路徑后方
location /data2/ {
root /data/;
autoindex on;
}
那我是否就可以通過調(diào)整目錄結(jié)構(gòu)讓這個請求能正常得到結(jié)果了呢?
現(xiàn)在調(diào)整目錄結(jié)構(gòu)為
-- data
---- data2
------ sitemap.xml
------ robots.txt
再次用 http://localhost/data2/sitemap.xml 請求,就會發(fā)現(xiàn)請求已經(jīng)正常了
alias
配置如下,配置沒有其他的變化,只是將 root 更改為了 alias 。重點關(guān)注配置文件中的 location /data/ 部分
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location /data/ {
alias /data/;
autoindex on;
}
}
代理的目錄結(jié)構(gòu)
我在 data 目錄下有兩個文件,文件名和內(nèi)容都不重要
-- data
---- sitemap.xml
---- robots.txt
這次直接就能訪問到了。不需要進行其他額外的配置
如果將上面的配置更改為
location /data/app/ {
alias /data/;
autoindex on;
}
那么請求的 url 將會變?yōu)?http://localhost/data/app/sitemap.xml 之后 nginx 的查找路徑會變?yōu)?/data/sitemap.xml
為了印證我們的猜想。我下面舉一個錯誤的例子
首先將配置更改為
location /data2/ {
alias /data/;
autoindex on;
}
目錄結(jié)構(gòu)調(diào)整為
我在 data 目錄下有兩個文件,文件名和內(nèi)容都不重要
-- data
---- sitemap.xml
---- robots.txt
---- app
------ sitemap2.xml
現(xiàn)在用 /data2/app/sitemap.xml 是可以正常訪問的,它被替換后的地址變成了 /data/app/sitemap.xml。我們有 app 這個目錄,所以不會報錯
但是如果把訪問的地址替換為 /data2/app2/sitemap.xml 就不行了,下面是 log
2024/04/25 05:40:53 [error] 26#26: *6 open() "/data/app2/sitemap.xml" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /data2/app2/sitemap.xml HTTP/1.1", host: "127.0.0.1"
可以看到 /data2/app2/sitemap.xml 被替換為了 /data/app2/sitemap.xml 我們并沒有 /app2 這個目錄。所以會報錯 404