Nginx 配置中 root 和 alias 的区别

下面这个解答是来自于 ChatGPT,在后面我添加了一些案例和测试过程

Root 和 Alias 是 nginx 中用于设置文件路径的两个指令,它们在使用场景和效果上有一些区别:

  1. root指令
    • root 指令用于定义请求的根目录。在一个 server 块中,它定义了所有请求的根目录。
    • 当请求到达时,nginx 会将 URI 添加到 root 指定的路径上,以确定请求的实际文件路径。
    • 例如,如果 root /usr/share/nginx/html; 设置在 server 块中,那么对于 URI /index.html,nginx 将尝试在 /usr/share/nginx/html/index.html 中查找文件。
  2. 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 指定的路径上。

如果看起来似乎还是有点不太理解,我来再进行解答一次。如果还不理解,在后面还有我测试的一些记录

声明:以下内容仅是我个人的理解,若有解答的不全或解答错误,还望补充与教导,谢谢

  1. root 指令

    • root 指令用于定义请求的根目录。在一个 server 块中,它定义了所有请求的根目录。这个应该好理解
    • 当请求到达时,nginx 会将 URI 添加到 root 指定的路径上,以确定请求的实际文件路径。(注意看黑体的地方)

    例子1:如果 root /usr/share/nginx/html; 设置在 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 中查找文件

通过上面的三个例子,可以在最后得出结论:

当配置为 root ,请求到达时。nginx 会将请求的路径拼接到 root 后面,也就是说会将你配置的 root 作为根节点

  1. 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

结论

  1. 配置为 root 时,nginx 会将到达的请求,拼接到配置的 root 路径后方
  2. 配置为 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 去访问页面的时候,按我的惯有思维,应该是这么理解的

  1. 首先nginx解析到 /data/ 路径,
  2. 根据 /data/ 的配置找到 root 这个配置路径
  3. 根据 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容