585

我需要通过我的应用程序服务器提供我的应用程序8080,并从一个目录提供我的静态文件,而无需接触应用程序服务器。我拥有的 nginx 配置是这样的......

    # app server on port 8080
    # nginx listens on port 8123
    server {
            listen          8123;
            access_log      off;

            location /static/ {
                    # root /var/www/app/static/;
                    alias /var/www/app/static/;
                    autoindex off;
            }


            location / {
                    proxy_pass              http://127.0.0.1:8080;
                    proxy_set_header        Host             $host;
                    proxy_set_header        X-Real-IP        $remote_addr;
                    proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
            }
    }

现在,有了这个配置,一切正常。请注意,该root指令已被注释掉。

如果我激活root和停用alias-- 它会停止工作。但是,当我/static/从它中删除尾随时,root它又开始工作了。

有人可以解释发生了什么。还请清楚详细地解释 和 之间的区别root及其alias用途。

4

8 回答 8

1297

rootalias指令之间有一个非常重要的区别。这种差异存在于处理rootalias处理中指定的路径的方式上。

root

  • location部分附加到root部分
  • 最终路径 = root+location

alias

  • location零件被零件alias替换
  • 最终路径 =alias

为了显示:

假设我们有配置

location /static/ {
    root /var/www/app/static/;
    autoindex off;
}

在这种情况下,Nginx 将派生的最终路径将是

/var/www/app/static/static

这将返回404,因为没有static/内部static/

这是因为位置部分附加到root. 因此,与root,正确的方法是

location /static/ {
    root /var/www/app/;
    autoindex off;
}

另一方面,随着alias,位置部分被丢弃。所以对于配置

location /static/ {
    alias /var/www/app/static/;
    autoindex off;           ↑
}                            |
                             pay attention to this trailing slash

最终路径将正确形成为

/var/www/app/static

在某种程度上,这是有道理的。alias只需让您定义一条新路径来表示现有的“真实”路径。位置部分是新路径,因此它被替换为真实路径。将其视为符号链接。

另一方面,根不是一条新路径,它包含一些必须与其他信息进行比较才能形成最终路径的信息。因此,位置部分被使用,而不是被丢弃。

尾部斜线的情况alias

对于每个Nginx 文档是否强制使用斜杠,没有明确的指导方针,但这里和其他地方的人们的共同观察似乎表明它是强制性的。

更多的地方已经讨论过这个问题,虽然不是最终的。

https://serverfault.com/questions/376162/how-can-i-create-a-location-in-nginx-that-works-with-and-without-a-trailing-slas

https://serverfault.com/questions/375602/why-is-my-nginx-alias-not-working

于 2012-05-18T05:18:29.383 回答
136

正如@treecoder 所说

root指令的情况下,完整路径被附加到包含位置部分的根,而在alias指令的情况下,只有不包括位置部分的路径部分被附加到别名。

一张图片胜过千言万语

对于root

在此处输入图像描述

对于alias

在此处输入图像描述

于 2016-10-09T03:03:54.240 回答
41

在您的情况下,您可以使用root指令,因为$urilocation指令的一部分与最后一个root指令部分相同。

Nginx 文档也建议它:
当位置与指令值的最后一部分匹配时:

location /images/ {
    alias /data/w3/images/;
}

最好使用 root 指令:

location /images/ {
    root /data/w3;
}

root指令将附加$uri到路径。

于 2015-07-01T06:03:02.857 回答
23

只是对@good_computer 非常有用的答案的快速补充,我想用文件夹替换 URL 的根目录,但前提是它与包含静态文件的子文件夹匹配(我想将其保留为路径的一部分)。

例如,如果请求的文件在/app/js/app/css中,则在 中查找/app/location/public/[that folder]

我使用正则表达式让它工作。

 location ~ ^/app/((images/|stylesheets/|javascripts/).*)$ {
     alias /home/user/sites/app/public/$1;
     access_log off;
     expires max;
 }
于 2014-10-05T16:38:31.280 回答
8

alias用于替换请求路径中的位置部分路径 (LPP),而root用于添加到请求路径中。

它们是将请求路径映射到最终文件路径的两种方式。

alias只能在 location 块中使用,它会覆盖 outside root

alias并且root不能一起用于位置块。

于 2019-05-25T09:33:02.690 回答
3
server {
    server_name xyz.com;
    root /home/ubuntu/project_folder/;

    client_max_body_size 10M;
    access_log  /var/log/nginx/project.access.log;
    error_log  /var/log/nginx/project.error.log;

    location /static {
        index index.html;
    }

    location /media {
        alias /home/ubuntu/project/media/;
    }
}

服务器块在 nginx 上运行静态页面。

于 2017-09-16T08:15:29.523 回答
2

换句话说,保持简短:在 的情况下root,指定的 location 参数是文件系统路径和 URI 的一部分。另一方面 -alias位置语句的 for 指令参数仅是 URI的一部分

因此,alias是一个不同的名称,它将某个 URI 映射到文件系统中的某个路径,而root将 location 参数附加到作为root指令参数给出的根路径。

于 2019-05-11T16:29:59.347 回答
2

虽然不需要我的回答,但我认为有必要添加它,root并且alias在使用正则表达式时会有所不同。

 location ~ /static/my.png$ {
     alias /var/www/static/;
     access_log off;
     expires max;
 }

在这种情况下,正则表达式匹配不会添加别名,nginx 只会搜索/var/www/static/not /var/www/static/my.png。您必须使用正则表达式捕获。

 location ~ /static/my.png$ {
     root /var/www;
     access_log off;
     expires max;
 }

在这种情况下,匹配的 url 将添加 root,nginx 将搜索/var/www/static/my.png.

于 2021-04-03T11:13:35.757 回答