【问题标题】:Nginx -- static file serving confusion with root & aliasNginx——静态文件与根和别名混淆
【发布时间】:2012-05-24 19:21:06
【问题描述】:

我需要通过我的应用服务器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 - 它会停止工作。但是,当我从 root 中删除尾随 /static/ 时,它又开始工作了。

谁能解释发生了什么。还请详细说明rootalias的区别和用途。

【问题讨论】:

    标签: nginx


    【解决方案1】:

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

    root 指令的情况下,完整路径被附加到根包括位置部分,而在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 documentation 是否强制使用尾部斜杠,没有明确的指导方针,但这里和其他地方的人们的普遍观察似乎表明它是。

    还有一些地方已经讨论过这个问题,但还没有定论。

    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

    【讨论】:

    • 别名路径后面的斜杠是必不可少的!
    • 这一切都很好(它帮助我解决了我的配置问题),但我想知道人们可以使用哪些日志记录设置来帮助诊断这类问题?就像,任何会打印到日志的东西,比如“收到的 [...] 请求,与“位置 [...]”配置块匹配,搜索目录 [...]”
    • @Pistos:将log_format scripts '$document_root | $uri | > $request'; 放入http 部分,将access_log /var/log/nginx/scripts.log scripts; 放入server nginx 配置部分。
    • 谢谢!确实,别名的尾部斜杠是必不可少的,否则我得到nginx: [emerg] invalid number of arguments in "alias" directive,并且服务器在重新启动期间出现故障。
    • @mafrosis 为什么它很重要?
    【解决方案2】:

    就像@treecoder 说的那样

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

    一张图抵千言

    对于root

    对于alias

    【讨论】:

    • 第二张图片中的第一个箭头应该是“+”吗?
    【解决方案3】:

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

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

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

    最好使用 root 指令:

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

    并且root 指令会将$uri 附加到路径中。

    【讨论】:

    • 为什么更好?文档也没有说。
    • 我看到的好处是避免重复 $uri, /images 在给定的例子中,当使用别名时
    【解决方案4】:

    只是对@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;
     }
    

    【讨论】:

    • 感谢您的回答。我知道这是 3 年后的事了,但是谁能解释一下使用别名与 root 之间是否存在性能和/或安全性权衡?
    • @Mina 如果可以的话最好使用root。 (文档中有注释wiki.nginx.org/HttpCoreModule#alias
    • 这正是我来这里的目的??
    • 两者都是安全的,但是在使用位置不以 / 结尾的别名时要小心,这是一个漏洞github.com/yandex/gixy/blob/master/docs/en/plugins/…
    【解决方案5】:

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

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

    alias只能用于位置块,它会覆盖外部的root

    aliasroot 不能一起用于位置块。

    【讨论】:

      【解决方案6】:
      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 上运行静态页面的服务器块。

      【讨论】:

      【解决方案7】:

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

      的一部分

      所以,alias 是一个不同的名称,它将特定 URI 映射到文件系统中的特定路径,而 root 将位置参数附加到作为参数提供给 root 指令的根路径。

      【讨论】:

        【解决方案8】:

        虽然不需要我的回答,但我认为有必要添加这个,rootalias 在使用正则表达式时的工作方式不同。

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

        在这种情况下,正则表达式匹配不会添加别名,nginx 将仅搜索 /var/www/static/ 而不是 /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

        【讨论】:

          猜你喜欢
          • 2012-01-05
          • 1970-01-01
          • 2017-05-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-14
          • 2012-08-30
          • 2011-01-15
          相关资源
          最近更新 更多