Я сейчас настраиваю обработку nginx некоторых страниц ошибок и других медиа-файлов «по умолчанию» (таких как favicon.ico и robots.txt), и столкнулся с небольшой проблемой, заставляющей вещи работать так, как я хочу, для определенных страниц ошибок ,
По сути, я пытаюсь обслуживать определенные файлы для сервера в корневом каталоге этого сервера, например /var/www/someserver.com/robots.txt. Если этот файл не существует, я хочу, чтобы nginx перешел в «default», то есть /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/. Он не возвращается к каталогу по умолчанию, если этот файл не существует.
Во всяком случае, вы можете, вероятно, то, что я пытался достичь (поэтому я включил первый рабочий пример).
Любые идеи?
Редактировать:
Основываясь на ответе Мартина Ф., вот что я закончил:
# Doesn't work when error page is returned on a POST request
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 и местоположений выше находится в файле server_defaults.conf, который включается в каждый виртуальный хост, поэтому я не жестко прописал путь к каждому местоположению и использовал относительный путь для значений по умолчанию.
Изменить 2:
У этого подхода есть проблема. Если вы отправляете POST по URL, который возвращает ошибку, метод запроса POST отправляется с попытками try_files. Это (для меня) приводит к ошибке 405 Not Allowed, потому что nginx, по сути, пытается POST, например, /default/500.html вместо того, чтобы просто получить эту страницу.
Изменить 3:
Я опубликовал решение, которое работает намного ближе к моей первоначальной идее.
log_not_found off;
и добавитьinternal;
вместо этого.try_files это путь сюда. Следующая конфигурация должна работать, но я не проверял ее на синтаксические ошибки.
источник
К сожалению, я опоздал с ответом на пару лет, но я подумал, что он может помочь будущим поисковикам. Моя установленная версия Nginx - 1.2.4, и я создал следующий фрагмент конфигурации:
источник
internal
.Я обнаружил, что крайне важно включить "proxy_intercept_errors on;" в любом блоке местоположения, где также была включена error_page.
Без этой настройки блок местоположения будет перехватывать коды ошибок, возвращаемые из восходящего потока.
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors
источник