【问题标题】:Nginx is serving the default content instead of my contentNginx 提供默认内容而不是我的内容
【发布时间】:2018-07-19 04:48:37
【问题描述】:

我有一个nginx version: nginx/1.10.3 (Ubuntu)Ubuntu 16.04.2 LTS 上运行。

我使用nginx 提供静态文件,webpack 生成的捆绑包,但这无关紧要。

我想要实现的是:

example.com 我想为/home/bundles/main/index.html 服务。我可以做到。

projects.example.com/project_1 我想服务/home/bundles/project_1/index.html

projects.example.com/project_2 我想服务/home/bundles/project_2/index.html

最后两个,我做不到。当我转到 projects.example.com/project_1projects.example.com/project_2 时,我会看到默认的 nginx 页面。

为了让事情更混乱,/etc/nginx/sites-enabled/default 被完全注释掉了。

此外,如果在projects.example.comlocation 块中,我将project_1 替换为/,我将获得该特定项目的服务,但我将无法为其他项目服务。

下面,我将向你展示我的 nginx 配置


server {
    listen 80;
    server_name example.com;

    location / {
        root /home/bundles/main;
        try_files $uri /index.html;
    }

    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name example.com;

    location / {
        root /home/bundles/main;
        try_files $uri /index.html;
    }

    ssl_certificate ...
    ssl_certificate_key ...
}

server {
    listen 80;
    server_name projects.example.com;

    location /project_1 {
        root /home/bundles/project_1;
        try_files $uri /index.html;
    }

    location /project_2 {
        root /home/bundles/project_2;
        try_files $uri /index.html;
    }

    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name projects.example.com;

    location /project_1 {
        root /home/bundles/project_1;
        try_files $uri /index.html;
    }

    location /project_2 {
        root /home/bundles/project_2;
        try_files $uri /index.html;
    }

    ssl_certificate ...
    ssl_certificate_key ...
}

感谢您的帮助!


编辑

我的答案

我找到的解决方案是将root 更改为alias

server {
    listen 80;
    server_name example.com;

    location / {
        root /home/bundles/main;
        try_files $uri /index.html;
    }

    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name example.com;

    location / {
        root /home/bundles/main;
        try_files $uri /index.html;
    }

    ssl_certificate ...
    ssl_certificate_key ...
}

server {
    listen 80;
    server_name projects.example.com;

    location /project_1 {
        alias /home/bundles/project_1;
        index index.html;
    }

    location /project_2 {
        alias /home/bundles/project_2;
        index index.html;
    }

    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name projects.example.com;

    location /project_1 {
        alias /home/bundles/project_1;
        index index.html;
    }

    location /project_2 {
        alias /home/bundles/project_2;
        index index.html;
    }

    ssl_certificate ...
    ssl_certificate_key ...
}

解决方案基于这两个答案。第一个answer 展示了如何解决问题,第二个answer 解释了为什么alias 有效而root 无效。

引用@treecoder

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

在我的特殊情况下,这会翻译成这样;

使用rootnginx 尝试访问的路径将是/home/bundles/project_1/project_1

使用alias,它会访问正确的路径/home/bundles/project_1

回溯一级,例如,说:

root /home/bundles/ 也不是一个真正的选择。那是因为我的项目实际上并没有被称为project_1project_2。实际结构与此更相似。

/bundles 我有目录project_aproject_b。我想将project_1 路由到project_a 目录,将project_2 路由到project_b 目录。

这就是我使用alias的原因。

我希望这会有所帮助。

【问题讨论】:

    标签: nginx configuration server configuration-files nginx-location


    【解决方案1】:

    你有:

    location /project_1 {
        root /home/bundles/project_1;
        try_files $uri /index.html;
    }
    

    所以root 只为以/project_1 开头的URI 定义。对于任何其他 URI,将使用默认的 root

    如果您提供 URI /project_1/(带有尾随 /),假设 default index directive 有效,nginx 应该返回您的 /project_1/index.html 内容。

    但是,未找到 URI /project_1 - 因此返回 /index.html。 URI /index.html 不以/project_1 开头,因此使用默认根。


    如果您希望 URI /project_1 按预期工作,并且默认操作是转到项目的 index.html 文件,请更改 try_files 指令。

    location /project_1 {
        root /home/bundles/project_1;
        try_files $uri $uri/ /project_1/index.html;
    }
    

    请参阅this document 了解更多信息。


    由于两个项目共享一个共同的根,您可以简化如下:

    server {
        listen 80;
        server_name projects.example.com;
    
        root /home/bundles
        index index.html;
    
        location /project_1 {
            try_files $uri $uri/ /project_1/index.html;
        }
        location /project_2 {
            try_files $uri $uri/ /project_2/index.html;
        }
        location / {
            deny all;
        }
    }
    

    我添加了index 指令以避免依赖默认值(相同),并添加了location 块来拒绝访问项目之外的区域。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题...结果证明,对我来说,默认站点“超越”了我想要的辅助站点并提供默认文件...好吧,它允许 IP6 请求和我的新站点没有。

      这是我的 access.log 示例:

      ::1 - - [05/Sep/2020:15:05:16 -0600] "GET / HTTP/1.1" 200 40 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36"
      

      注意到::1 位了吗?那是我猜我的浏览器默认的 IP6 请求。所以我只是确保通过更改在我的站点配置文件中为相关站点启用本地 IP6 请求:

      listen 80;
      server_name example.local;
      

      到:

      listen 80;
      listen [::]:80;
      server_name example.local;
      

      就是这样。

      【讨论】:

        猜你喜欢
        • 2010-12-08
        • 1970-01-01
        • 2020-09-20
        • 1970-01-01
        • 2017-03-06
        • 2014-07-30
        • 2011-03-24
        • 1970-01-01
        • 2020-03-24
        相关资源
        最近更新 更多