nginx 中 404 页面的回退

nginx 中 404 页面的回退

我正在创建一个“userdir”配置,其中 Web 服务器为每个用户的 ~/www 目录内的文件提供服务。

我有以下配置片段:

server {
    listen 443;
    listen [::]:433;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    server_name ~^(?<user>\w+)\.example\.com$;

    root /var/www/userdir;
    index index.html;
    error_page 404 = @not_found;
    add_header X-User $user;

    location / {
        root /home/$user/www;
        try_files $uri $uri/ =404;
    }

    location @not_found {
        if (-f /home/$user/www/404.html)
        {
            root /home/$user/www;
        }

        try_files /404.html =500;
    }
}

当请求不存在的文件时,@not_found将输入指定的位置。它首先检查用户是否有自定义 404 页面,如果有,它会在尝试提供 404.html 之前将文档根目录设置为用户的目录。

但是配置块的结果是,如果用户目录中存在 404.html,则返回通用 nginx 404 页面;如果不存在,则返回 /var/www/userdir/404.html。

答案1

if在块内使用location是违反直觉的,因为这个文件说明。此外,使用error_page命名位置会将响应代码从 404 更改为 200,这可能不是所希望的。

您可以使用测试在块顶部设置一个变量server,然后可以使用它来设置错误页面文件的位置。

例如:

set $ERROR_ROOT "/var/www/userdir";
if (-f /home/$user/www/404.html) {
    set $ERROR_ROOT "/home/$user/www";
}

error_page 404 /404.html;

location / {
    root /home/$user/www;
    try_files $uri $uri/ =404;
}

location = /404.html {
    root $ERROR_ROOT;
}

答案2

这似乎可以解决问题:

location / {
    root /home/$user/www;
    try_files $uri $uri/ =404;
    error_page 404 /404.html;
}

您可能需要删除“error_page 404 = @not_found;”。

相关内容