【问题标题】:nginx: how to always return a custom 404 page for the default hostnginx:如何始终为默认主机返回自定义 404 页面
【发布时间】:2011-11-23 12:41:27
【问题描述】:

我有 nginx 0.8.53 配置了一些可以按需要工作的虚拟主机。但是,由于 nginx 在虚拟主机上的“最佳匹配”,我需要添加一个默认主机来捕获所有不针对特定虚拟主机的请求。我希望默认主机返回我创建的自定义 404 页面,而不是默认的 nginx 404 页面。

我认为我需要类似的东西:

# The default server:
server {
    listen       80 default_server;
    server_name  everythingelse;

    # Everything is a 404
    location / {
        return 404;
    }
    error_page 404 /opt/local/html/404.html;
}

但这仍然返回默认的 nginx 404 页面。 return 404 似乎忽略了 error_page 配置。

【问题讨论】:

    标签: nginx


    【解决方案1】:

    这是我的 conf 中的内容:

    # The default server.
    server {
      listen       80 default_server;
      server_name  everythingelse;
    
      error_page 404 /404.html;
    
      # Everything is a 404
      location / {
        return 404; #return the code 404
      }
    
      # link the code to the file
      location = /404.html {
        #EDIT this line to make it match the folder where there is your errors page
        #Dont forget to create 404.html in this folder
        root  /var/www/nginx/errors/;
      }
    }
    

    【讨论】:

    • 谢谢,这对我有用。顺便说一句,您可以忽略root /var/www/nginx/errors/; 中的最后一个/。写成root /var/www/nginx/errors;
    【解决方案2】:

    nginx 中很少有指令采用文件系统路径。你想要这样的东西:

    # The default server.
    server {
      listen       80 default_server;
      server_name  everythingelse;
    
      root /opt/local/html;
    
      error_page 404 /404.html;
    
      # Everything is a 404
      location / {
        return 404;
      }
    
      # EDIT: You may need this to prevent return 404; recursion
      location = /404.html {
        internal;
      }
    }
    

    【讨论】:

    • 你的代码会给他默认的 404 页面,他说他不想要(而且已经得到了),其次,error_page 指令允许你指定自定义错误页面。实际上,“error_page 404 /404.html”只是表示使用nginx安装文件夹中的404.html文件(默认为404文件)。这也可以是“error_page 404 /path/to/any/other/404.html”或者,他可以更改默认文件本身。
    • 默认的 404 页面根本不是文件,并且 error_page not 采用文件系统路径。它在内部重定向到给定的 uri,因此它会寻找 /404.html。可能需要添加 location = /404.html { internal; } 或类似的东西来防止显示默认的 404 页面,现在我考虑了一下,因为内部重定向最终会回到位置 / 并且我不确定返回 404 是什么;将在没有 recursive_error_pages 的情况下执行; (无论如何都会很糟糕)。
    • “默认的 404 页面根本不是文件”不正确。您可以在 /usr/share/nginx/html/ 文件夹中找到它(在 redhat 上 - 其他人可能会有所不同)。 error_page 指令采用一个 uri,它可以在 webroot 下或根据需要使用别名。
    • 也许redhat给你提供了一些通用的错误页面,但是原生的nginx错误页面是由src/http/ngx_http_special_response.c生成的。如果您不指定自定义 error_page,这将生成响应。正如我之前所说,error_page 采用 uri 参数,但 OP 和您的原始答案都将该参数视为文件系统路径。
    • location 和 error_page 的顺序无关紧要,所以只是移动它们并不会改变任何东西。我的配置和您修改后的配置都以(几乎)相同的方式返回错误页面。对 /foo 的请求进入,选择位置 /,返回 404 查找错误页面,找到它,执行到 /404.html 的内部重定向,它选择位置 /404.html。该位置使用默认(静态)内容处理程序,因此它使用服务器的根目录并以 404 状态提供 /opt/local/html/404.html。
    【解决方案3】:

    在调用 return 404 之前将 error_page 指令向上移动到 conf。

    这应该可行:

    # The default server.
    #
    server {
        listen       80 default_server;
        server_name  everythingelse;
        error_page 404 /error_docs/404.html;
    
        # Everything is a 404
        location / {
            return 404;
        }
    
        # Custom Error Page
        location /error_docs {
            alias /opt/local/html/;
            log_not_found  off;
            access_log off;
        }
    }
    

    这将为所有站点(服务器)使用相同的自定义。您需要添加错误文档位置。

    http {
    error_page 404 /error_docs/404.html;
    
    ...
    
        # The default server.
        #
        server {
            listen       80 default_server;
            server_name  everythingelse;
    
            # Everything is a 404
            location / {
                return 404;
            }
    
            # Custom Error Page
            location /error_docs {
                alias /opt/local/html/;
                log_not_found  off;
                access_log off;
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      server 块之前,您可能正在使用include 指令:

      include /etc/nginx/conf.d/*.conf;
      server {
          listen 80;
          ...
      }
      

      我遇到了同样的问题,并通过删除 include 行来修复它:

      server {
          listen 80;
          ...
      }
      

      【讨论】:

        【解决方案5】:

        在 NGINX v1.14(2019 年 12 月 26 日发布)中,您不能使用 location = /404.html。删除=(等号)有效:

        server {
            listen 80;
        
            server_name everythingelse;
            error_page 404 /404.html;
        
            location / {
                return 404;
            }
        
            location /404.html {
                root /opt/local/html;
            }
        }
        

        【讨论】:

          【解决方案6】:

          由于rooterror_page 都是http 块范围内的有效指令,因此可以利用nginx 配置的继承行为。

          为了在我的所有虚拟主机之间共享自定义错误页面(以便对未知虚拟主机或已知虚拟主机中不存在资源的请求根据 error_page 定义获取我的自定义错误页面作为响应),我使用以下方法。

          1.将这三行添加到/etc/nginx/nginx.conf

          # …
          root /var/www/whatever # Used by undefined hosts
          error_page 403 404 =404 /404.html
          error_page 502 503 504 =500 /500.html
          # …
          

          2. 使用以下 sn-p 创建 /etc/nginx/sites-available/catchall 作为 «catch all» 默认虚拟服务器。

          server {
              listen 80 default_server;
              listen [::]:80 default_server;
              # SSL rules here if required
              server_name _;
          }
          

          3. 在必须使用自定义错误的每个文档根目录中创建 404.html 和 500.html 文件(或链接 /var/www/whatever 中的错误),否则默认值将改为使用。

          也就是说,并非所有指令都可以从更高级别的范围继承,更糟糕的是,某些继承是不直观的,并且不符合您的预期。

          (使用Debian9nginx/1.10.3

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-11-04
            • 2011-11-08
            • 2012-04-24
            • 1970-01-01
            • 2011-10-17
            • 1970-01-01
            • 2015-08-12
            • 1970-01-01
            相关资源
            最近更新 更多