Рейтинг:1

Nginx try_files не работает внутри блока сервера

флаг ar
http {
включить mime.types;
default_type application/octet-stream;

сервер {
    корень/сайты;
    слушать 80;
    имя_сервера локальный хост;

    # не работает
    try_files /logo.png /logo.jpg /error;

    # работает
    переписать ^/е /ошибка;

    # работает
    # return 200 "$request_uri обрабатывается блоком сервера";

    место расположения / {
        default_type текстовый/обычный;
        return 200 "Корневой префикс совпал";
    }

    местоположение/ошибка {
        default_type текстовый/обычный;
        вернуть 404 "Лого не найдено";
    }
}

Я хочу знать, в чем причина такой оценки, я не смог найти надежного объяснения ни в документации, ни на форумах.

Кстати, я экспериментировал со следующим сценарием:

  • Удалил блок location/{} и все заработало как задумано. я знаю это когда запрос делается на сервер, он сначала оценивается сервером блок, а затем соответствующие блоки местоположения. Но кажется try_files директива игнорируется (ПОЧЕМУ?!!). Если я прав, последний аргумент try_files директива переписывает URI, поэтому он должен вести себя как перезапись директива. Директивы rewrite и return работали как положено, они оценивались каждый раз независимо от того, есть ли местонахождение блокировать совпадения или нет.

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

Richard Smith avatar
флаг jp
Ваше предположение, что «он сначала оценивается блоком сервера», неверно.
Safar Safarli avatar
флаг ar
@ Ричард Смит. Спасибо за внимание. Не могли бы вы объяснить, почему?
Ivan Shatsky avatar
флаг gr
@SafarSafarli Помимо того, что уже сказал Ричард Смит, вы должны знать, что существуют разные этапы обработки запросов. Ознакомьтесь с [документацией по разработке nginx](http://nginx.org/en/docs/dev/development_guide.html#http_phases) или [этой статьей](http://www.nginxguts.com/phases/) для получения дополнительной информации. Директивы из ngx_http_rewrite_module, размещенные на уровне сервера, обрабатываются во время NGX_HTTP_SERVER_REWRITE_PHASE, а директива try_files обрабатывается во время NGX_HTTP_PRECONTENT_PHASE.
Safar Safarli avatar
флаг ar
@IvanShatsky, спасибо за внимание.
Safar Safarli avatar
флаг ar
@IvanShatsky Я прочитал предоставленный вами раздел статьи.Но я нашел это немного сложным для понимания, например: «`ngx_http_try_files_module` и `ngx_http_mirror_module` регистрируют свои обработчики на этом этапе..». Вызов `ngx_http_try_files_module` в качестве модуля сбивает с толку, не следует ли вместо этого использовать слово «директива»?
Ivan Shatsky avatar
флаг gr
@SafarSafarli Директива `try_files` фактически находится в своем собственном [`ngx_http_try_files_module`](https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_try_files_module.c), а не в [`ngx_http_core_module` ](https://github.com/nginx/nginx/blob/master/src/http/ngx_http_core_module.c) (см. предоставленные ссылки GitHub на исходный код nginx).
Safar Safarli avatar
флаг ar
@IvanShatsky, тогда почему это указано как директива основного модуля? https://nginx.org/en/docs/http/ngx_http_core_module.html. Это так запутанно
Ivan Shatsky avatar
флаг gr
@SafarSafarli Я нашел ответ на твой вопрос. Это _было_ директивой основного модуля до редизайна, который произошел в 2017 году. До тех пор, пока эта директива `try_files` не использовала специальную `TRY_FILES_PHASE`, которая была доступна исключительно для `try_files` и никаких других директив. С редизайном в рабочий процесс обработки запросов nginx был добавлен новый `PRECONTENT_PHASE`, а реализация директивы `try_files` была перемещена в отдельный модуль, использующий эту фазу. Теперь любой сторонний модуль может использовать этот новый PRECONTENT_PHASE вместе с модулем nginx_http_try_files_module.
Ivan Shatsky avatar
флаг gr
@SafarSafarli Так что я думаю, что команда nginx просто решила не переписывать документацию. Есть небольшая разница с точки зрения конечного пользователя. Все равно нельзя отключить ни `nginx_http_core_module`, ни `nginx_http_try_files_module` при сборке nginx из исходников. Вы можете посмотреть вышеупомянутый коммит редизайна исходного кода nginx [здесь] (https://github.com/nginx/nginx/commit/129b06dc5dfab7b4513a4f274b3778cd9b8a6a22).
Рейтинг:0
флаг jp

See how nginx processes a request. But I will add a couple of caveats that specifically address your question and are easily observed but may not be well documented.

You mention rewrite and return directives, but these belong to the ngx_http_rewrite_module which have there own evaluation rules and do not behave the same as the core directives. You are correct that rewrite and return in server context can execute before the location block is selected.

As you have observed (with the exception of the ngx_http_rewrite_module), the server context acts like the default location, that is, if no other location block matches the request. The presence of an explicit location / { ... } block will always take precedence.

Safar Safarli avatar
флаг ar
Я понял, но мой вопрос в основном касается директивы «try_files». Не могли бы вы предоставить больше информации об этом. В данном случае в контексте сервера. Спасибо
Richard Smith avatar
флаг jp
У меня нет больше информации, так как я сказал, что это наблюдаемое поведение.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.