下面这个解答是来自于 ChatGPT,在后面我添加了一些案例和测试过程
Root 和 Alias 是 nginx 中用于设置文件路径的两个指令,它们在使用场景和效果上有一些区别:
- root指令:
root
指令用于定义请求的根目录。在一个 server 块中,它定义了所有请求的根目录。- 当请求到达时,nginx 会将 URI 添加到
root
指定的路径上,以确定请求的实际文件路径。- 例如,如果
root /usr/share/nginx/html;
设置在server
块中,那么对于 URI/index.html
,nginx 将尝试在/usr/share/nginx/html/index.html
中查找文件。- alias指令:
alias
指令用于为指定的 URI 创建一个别名路径,它允许将请求的 URI 与文件系统中的实际路径解耦。- 当请求到达时,nginx 会将 URI 替换为
alias
指定的路径,然后查找文件。- 例如,
alias /data/;
可以将 URI/data/index.html
映射到/data/index.html
。在你的配置中,
root
指令用于定义所有请求的根目录,而alias
指令用于为/data/
URI 创建一个别名路径。这意味着对于/data/
下的请求,nginx 将使用alias
指令提供的路径,而不是将 URI 添加到root
指定的路径上。
如果看起来似乎还是有点不太理解,我来再进行解答一次。如果还不理解,在后面还有我测试的一些记录
声明:以下内容仅是我个人的理解,若有解答的不全或解答错误,还望补充与教导,谢谢
-
root 指令
-
root
指令用于定义请求的根目录。在一个 server 块中,它定义了所有请求的根目录。这个应该好理解 - 当请求到达时,nginx 会将 URI 添加到
root
指定的路径上,以确定请求的实际文件路径。(注意看黑体的地方)
例子1:如果
root /usr/share/nginx/html;
设置在server
块中,那么对于 URI/index.html
,nginx 将尝试在/usr/share/nginx/html/index.html
中查找文件。只看上面一个例子,可能不好理解,那我再加一些例子增加助于理解
例子2:如果
root /usr/share/nginx/html;
设置在server
块中,那么对于 URI/app/index.html
,nginx 将尝试在/usr/share/nginx/html/app/index.html
中查找文件。例子3:
location /data2/ { root /usr/share/nginx/html/; autoindex on; }
如果是上面这种配置。那么对于 URI
/data2/app/index.html
,nginx将尝试在/usr/share/nginx/html/data2/app/index.html
中查找文件通过上面的三个例子,可以在最后得出结论:
当配置为 root ,请求到达时。nginx 会将请求的路径拼接到 root 后面,也就是说会将你配置的 root 作为根节点
-
-
alias 指令
-
alias
指令用于为指定的 URI 创建一个别名路径,它允许将请求的 URI 与文件系统中的实际路径解耦。 - 当请求到达时,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
-
结论
- 配置为 root 时,nginx 会将到达的请求,拼接到配置的 root 路径后方
- 配置为 alias 时,nginx 会将到达的请求,替换为 alias 后配置的路径
接下来我通过一个实际的例子以及日志来解答这个问题
root
配置如下,重点关注配置文件中的 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;
}
}
代理的目录结构
我在 data 目录下有两个文件,文件名和内容都不重要
-- data
---- sitemap.xml
---- robots.txt
现在我使用的是 root 的方式配置的。
当我使用 http://localhost/data/sitemap.xml 去访问页面的时候,按我的惯有思维,应该是这么理解的
- 首先nginx解析到 /data/ 路径,
- 根据 /data/ 的配置找到 root 这个配置路径
- 根据 sitemap.xml 这个文件。从 root 配置的这个路径后去取实际的这个文件
但是我得到的结果却是 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 实际就会触发下面的这个规则
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 这个路径了。看起来是不是有点像是把我请求的路径给拼接到了 root 中配置的路径的后面?
实验一下。修改配置文件
location /data2/ {
root /data/;
autoindex on;
}
现在我使用新的连接访问看得到的是什么样的结果
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"
根据日志,印证了我的猜想。
当我用下面这种带有路径的规则时。Nginx 会将我 URL 中的路径拼接到配置的 root 路径后方
location /data2/ {
root /data/;
autoindex on;
}
那我是否就可以通过调整目录结构让这个请求能正常得到结果了呢?
现在调整目录结构为
-- data
---- data2
------ sitemap.xml
------ robots.txt
再次用 http://localhost/data2/sitemap.xml 请求,就会发现请求已经正常了
alias
配置如下,配置没有其他的变化,只是将 root 更改为了 alias 。重点关注配置文件中的 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;
}
}
代理的目录结构
我在 data 目录下有两个文件,文件名和内容都不重要
-- data
---- sitemap.xml
---- robots.txt
这次直接就能访问到了。不需要进行其他额外的配置
如果将上面的配置更改为
location /data/app/ {
alias /data/;
autoindex on;
}
那么请求的 url 将会变为 http://localhost/data/app/sitemap.xml 之后 nginx 的查找路径会变为 /data/sitemap.xml
为了印证我们的猜想。我下面举一个错误的例子
首先将配置更改为
location /data2/ {
alias /data/;
autoindex on;
}
目录结构调整为
我在 data 目录下有两个文件,文件名和内容都不重要
-- data
---- sitemap.xml
---- robots.txt
---- app
------ sitemap2.xml
现在用 /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
网友评论