我需要通过我的应用程序服务器在8080服务我的应用程序,我的静态文件从一个目录不接触应用程序服务器。

    # 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;
            }
    }

现在,有了这个配置,一切工作正常。注意,根指令被注释掉了。

如果我激活根并停用别名,它将停止工作。然而,当我从根目录中删除尾随的/static/时,它又开始工作了。

有人能解释一下这是怎么回事吗?


当前回答

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

root

位置部分被附加到根部分 最终路径=根+位置

别名

位置部分被别名部分取代 最终路径= alias

说明:

假设我们有配置

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

在这种情况下,Nginx将导出的最终路径将是

/var/www/app/static/static

这将返回404,因为在static/中没有static/

这是因为位置部分被追加到根目录中指定的路径。因此,使用root,正确的方法是

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

另一方面,使用别名时,位置部分将被删除。对于配置

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

最终路径将正确地形成为

/var/www/app/static

在某种程度上,这是有道理的。别名只是让您定义一个新路径来表示一个现有的“真实”路径。位置部分是新路径,因此它被替换为实际路径。把它看作一个符号链接。

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

别名中尾随斜杠的情况

对于每个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

其他回答

在你的例子中,你可以使用根指令,因为location指令的$uri部分与上一个根指令部分相同。

Nginx文档也给出了建议: 当location匹配指令值的最后一部分时: 位置/图像/ { 别名/数据/ w3 /图像/; } 最好使用root指令: 位置/图像/ { 根/数据/ w3; }

根指令会将$uri附加到路径中。

虽然我的答案是不需要的,但我认为有必要添加这一点,根和别名的工作方式不同,当涉及到正则表达式。

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

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

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

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

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

root

位置部分被附加到根部分 最终路径=根+位置

别名

位置部分被别名部分取代 最终路径= alias

说明:

假设我们有配置

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

在这种情况下,Nginx将导出的最终路径将是

/var/www/app/static/static

这将返回404,因为在static/中没有static/

这是因为位置部分被追加到根目录中指定的路径。因此,使用root,正确的方法是

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

另一方面,使用别名时,位置部分将被删除。对于配置

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

最终路径将正确地形成为

/var/www/app/static

在某种程度上,这是有道理的。别名只是让您定义一个新路径来表示一个现有的“真实”路径。位置部分是新路径,因此它被替换为实际路径。把它看作一个符号链接。

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

别名中尾随斜杠的情况

对于每个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

比如@treecoder

对于根指令,完整的路径被附加到根,包括位置部分,而对于别名指令,只有路径中不包括位置部分的部分被附加到别名。

一幅图胜过千言万语

根:

别名:

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

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

别名只能在位置块中使用,它将覆盖外部根。

别名和根不能在位置块中同时使用。