Как настроить страницу ошибки резервирования в nginx?

Вопрос или проблема

Я настраиваю обработку некоторых страниц ошибок и других “стандартных” медиафайлов (таких как favicon.ico и robots.txt) в nginx на данный момент, и столкнулся с небольшой проблемой в том, чтобы всё работало так, как я хочу для определенных страниц ошибок.

В основном, я пытаюсь предоставить определенные файлы для сервера под корнем этого сервера, например, /var/www/someserver.com/robots.txt. Если этот файл не существует, я хочу, чтобы nginx переходил к “по умолчанию”, т.е. /var/www/default/robots.txt. Это основной смысл того, как я это (успешно) настроил:

server {
    ...
    root /var/www/someserver.com;

    location ~* ^/(robots\.txt)$ {
        error_page 404 = @default;
    }

    location @default {
        root /var/www/default;
    }
}

Это работает отлично.

Я пытаюсь сделать то же самое для страниц ошибок, но не могу этого достичь:

server {
    ...
    root /var/www/someserver.com;

    error_page 404   /404.html;

    location ~* ^/(404\.html)$ {
        error_page 404 = @default;
    }

    location @default {
        root /var/www/default;
    }
}

Обратите внимание, что это “работает” в том смысле, что если вы посетите someserver.com/404.html, он сначала попытается загрузить /var/www/someserver.com/404.html, а затем перейдёт к /var/www/default/404.html, если это не будет найдено. Однако, если вы посетите someserver.com/blahblah, он показывает страницу 404 только если она установлена в /var/www/someserver.com/. Он не переходит к каталогу по умолчанию, если этот файл не существует.

Тем не менее, вы, вероятно, понимаете, что я пытался достичь этого (вот почему я включил первый рабочий пример).

Есть идеи?

Редактирование:

Исходя из ответа Мартина Ф, вот что я в итоге собрал вместе:

# Не работает, когда страница ошибки возвращается на POST-запрос
server {
    ...
    root /var/www/someserver.com;

    error_page  404         = @notfound;
    error_page  500 502 504 = @server_error;
    error_page  503         = @maintenance;

    location @notfound {
        try_files /404.html /../default/404.html =404;
    }

    location @server_error {
        try_files /500.html /../default/500.html =500;
    }

    location @maintenance {
        try_files /503.html /../default/503.html =503;
    }
}

Это работает отлично. Фактический блок error_pages и locations выше находится в файле server_defaults.conf, который включается в каждый виртуальный хост, вот почему я не закодировал путь в каждый location и использовал относительный путь для значений по умолчанию.

Редактирование 2:

Этот подход имеет проблему. Если вы отправляете POST на URL, который возвращает ошибку, метод запроса POST отправляется с попытками try_files. Это (для меня) приводит к ошибке 405 Not Allowed, потому что nginx по сути пытается сделать POST на, например, /default/500.html вместо того, чтобы просто получить эту страницу.

Редактирование 3:

Я опубликовал решение, которое работает и гораздо ближе к моей первоначальной идее.

В итоге я пошёл с чем-то гораздо ближе к моей первоначальной идее. Ключом, который мне не хватало, оказалось направление recursive_error_pages. Всё, что мне действительно нужно было сделать, это включить это “включить”, и моя первоначальная идея сработала. Вот как выглядит соответствующая часть моего конфигурационного файла сейчас:

server {
    ...

    root /var/www/someserver.com/;

    error_page 400 404      /404.html;
    error_page 500 502 504  /500.html;
    error_page 503          /503.html;

    recursive_error_pages   on;

    location ~* ^/(404\.html|500\.html|503\.html)$ {
        log_not_found off;
        error_page 404 = @default;
    }

    location @default {
        log_not_found on;
        root /var/www/default;
    }
}

Я включил другие типы ошибок, которые не входили в мой первоначальный вопрос, потому что это и вызвало у меня трудности с подходом Мартина Ф, который в остальном был отличным. Директива log_not_found просто обеспечивает то, что у меня нет 404 в моём журнале, когда страница ошибки не найдена в исходном корне.

try_files — это правильный подход здесь. Следующая конфигурация должна сработать, но я не проверял её на наличие ошибок синтаксиса.

server {
    ...
    root /var/www;

    location / {
        try_files /someserver.com$uri /default$uri /someserver.com$uri/ /default$uri/ @notfound;
    }

    location @notfound {
       try_files /someserver/404.html /default/404.html =404; # =404 должно заставить использовать стандартную страницу 404 nginx.
    }
}

К сожалению, я немного запоздал с моим ответом, но я думал, что это может помочь будущим искателям. Моя установленная версия Nginx — 1.2.4, и я создал следующий фрагмент конфигурации:

server {

server_name www.example.com
root /var/www/example


## Ошибки -> Локации
error_page   400 /400.html;
error_page   403 /403.html;
error_page   404 /404.html;
error_page   500 502 503 504 /50x.html;

## Локации -> Резервное копирование
location = /400.html {
    try_files /400.html @error;
    internal;
}
location = /403.html {
    try_files /403.html @error;
    internal;
}
location = /404.html {
    try_files /404.html @error;
    internal;
}
location = /50x.html {
    try_files /50x.html @error;
    internal;
}

## Директория резервного копирования
location @error {
    root /var/www/error;
}

}

Я обнаружил, что крайне важно включить “proxy_intercept_errors on;” в любом блоке локации, где также включена ошибка_page.

Без этой настройки блок локации будет перехватывать коды ошибок, возвращающиеся от upstream.

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors

Вот как вы можете обойти проблему “405 Not Allowed”. Что-то вроде этого:

http {
  map $request_method $x_static_content_denied {
    default 1;
    GET     0;
    HEAD    0;
  }

# ...

server {
    # ...
    error_page  500 502 504 = @server_error;
    # ...
    location @server_error {
      if ($x_static_content_denied) { return 500; }
      try_files  /500.html /../default/500.html =500;
    }
  }
}

Он возвращает стандартную страницу ошибки nginx в случае, если статическое содержимое не разрешено.

Ответ или решение

Настройка страницы ошибок с резервным копированием в Nginx

Настройка серверов Nginx для обработки страниц ошибок играет ключевую роль в создании качественного пользовательского опыта. В данной статье мы подробно рассмотрим, как настроить резервные страницы ошибок и файлов, таких как robots.txt и категории ошибок, чтобы при отсутствии страницы в основном каталоге был доступен запасной вариант.

Основная концепция

Для начала, необходимо понимать, что в Nginx можно настроить обработку ошибок, используя директивы error_page и try_files. Эти инструменты позволяют вам отправлять пользователя на определенные страницы ошибок, а также на страницы, которые служат резервом.

Пример конфигурации

Ниже приведен пример конфигурации Nginx, который иллюстрирует, как настроить резервирование:

server {
    listen 80;
    server_name someserver.com;

    root /var/www/someserver.com;

    # Обрабатываем различные коды ошибок
    error_page 400 404 /404.html; 
    error_page 500 502 504 /500.html; 
    error_page 503 /503.html; 

    # Включаем рекурсивную обработку ошибок для страниц
    recursive_error_pages on;

    # Локация для обработки поиска ошибок 404
    location = /404.html {
        try_files /404.html @default;
        internal;
    }

    # Локация для обработки поиска ошибок 500
    location = /500.html {
        try_files /500.html @default;
        internal;
    }

    # Локация для обработки резервных страниц
    location @default {
        root /var/www/default;
        try_files /404.html /500.html =404;
    }
}

Пояснение конфигурации

  1. Директивы error_page: Используются для указания пользовательских страниц ошибок, которые будут отображаться при возникновении определённых ошибок, таких как 404 (Не найдено) или 500 (Внутренняя ошибка сервера).

  2. recursive_error_pages: Включение этой директивы позволяет Nginx рекурсивно обрабатывать страницы ошибок, что означает, что если указанная страница ошибки (например, 404.html) не найдена, то будет использоваться резервная, указанный в директории, в данном случае /var/www/default.

  3. Локации для обработки: В конфигурации предусмотрены специальные локации, которые обрабатывают запросы к страницам ошибок. Если пользователь запрашивает страницу ошибки прямым запросом, то сначала проверяется наличие файла в основном каталоге. Если файл отсутствует, управление передается к резервной локации (@default).

  4. Использование try_files: Эта директива позволяет проверять наличие файлов в указанном порядке. В случае, если первый файл не найден, проверяется следующий.

Основные проблемы и их решения

1. Ошибка "405 Not Allowed"

Проблема может возникнуть, если пользователь сталкивается с кодом ошибки из-за метода POST. В этом случае обратите внимание на директиву proxy_intercept_errors, которая должна быть включена в конфигурации:

location @server_error {
    proxy_intercept_errors on;
    try_files /500.html /../default/500.html =500;
}

Это обеспечит корректное поведение сервера, избегая ошибок при обработке POST-запросов.

2. Логирование ошибок

Используйте директиву log_not_found для минимизации запретов в логах, если файла ошибки не существует в основном каталоге:

location ~* ^/(404\.html|500\.html|503\.html)$ {
    log_not_found off;
    error_page 404 = @default;
}

Заключение

Правильная настройка страницы ошибок с резервным вариантом в Nginx – это важный шаг к обеспечению высокого уровня пользовательского опыта. Используя приведенные выше рекомендации и настройки, вы сможете настроить надежный механизм обработки ошибок, который улучшит взаимодействие пользователей с вашим сайтом.

SEO-оптимизация

Для улучшения видимости вашей конфигурации в поисковых системах, исходя из ключевых слов, таких как "настройка Nginx", "страницы ошибок Nginx", "резервные страницы" и "обработка ошибок Nginx", вы можете рассмотреть возможность добавления дополнительных материалов или часто задаваемых вопросов, касающихся этой темы.

Оцените материал
Добавить комментарий

Капча загружается...