Как работает try_files?

72

Я посмотрел документацию по nginx, и она все еще смущает меня.

Как try_filesработает? Вот что говорится в документации:

Из NginxHttpCoreModule

try_files

синтаксис: try_files путь1 [путь2] uri

по умолчанию: нет

контекст: сервер, местоположение

доступность: 0.7.27

Проверяет наличие файлов по порядку и возвращает первый найденный файл. Завершающий слеш указывает на каталог - $ uri /. Если файл не найден, вызывается внутреннее перенаправление на последний параметр. Последний параметр является резервным URI и должен существовать, иначе возникнет внутренняя ошибка. В отличие от перезаписи, $ args не сохраняется автоматически, если резервный вариант не является именованным местоположением. Если вам нужно сохранить аргументы, вы должны сделать это явно:

Я не понимаю, как он проверяет пути и что, если я не хочу внутренней ошибки, но должен ли он возобновить оставшуюся часть пути, чтобы найти другой файл?

Если я захочу попробовать кэшированный файл /path/app/cache/url/index.htmlи если он не удастся попробовать, /path/app/index.phpкак я это напишу? Если бы я написал:

try_files /path/app/cache/ $uri
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php-fastcgi/php-fastcgi.socket;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;

У меня есть index index.php index.html index.htm;. Когда я приезжаю /urlname, он будет пытаться проверить /path/app/cache/urlname/index.phpто /path/app/cache/urlname/index.html? Если мы проигнорируем все после try_filesтого, можно try_filesли проверить папку кэша? Я пытался и потерпел неудачу.

76484
источник

Ответы:

64

try_files пытается определить буквальный путь, который вы указали относительно определенной корневой директивы, и устанавливает внутренний указатель файла. Если вы используете, например, try_files /app/cache/ $uri @fallback;с, index index.php index.html;то он будет проверять пути в следующем порядке:

  1. $document_root/app/cache/index.php
  2. $document_root/app/cache/index.html
  3. $document_root$uri

перед окончательным внутренним перенаправлением на @fallback с именем location. Вы также можете использовать файл или код состояния ( =404) в качестве последнего параметра, но при использовании файла он должен существовать .

Вы должны заметить, что try_files сам по себе не выдаст внутреннего перенаправления ни для чего, кроме последнего параметра. Это означает, что вы не можете сделать следующее: так try_files $uri /cache.php @fallback;как это приведет к тому, что nginx установит внутренний указатель файла на $ document_root / cache.php и будет обслуживать его, но поскольку внутреннее перенаправление не происходит, местоположения не переоцениваются, и поэтому оно будет служил простым текстом. (Причина, по которой он работает с файлами PHP в качестве индекса, заключается в том, что директива index будет выполнять внутреннее перенаправление)

Мартин Фьордвальд
источник
2
Это намного яснее. Благодарю. Я немного не уверен, как работает названное местоположение. Если у @fallback есть строки для fastcgi php, которые будут использоваться как php-файл, а не как текст? Используется ли запасной вариант, когда все до того, как оно выходит из строя?
2
Именованное местоположение просто функционально идентично обычному местоположению, за исключением того, что к нему можно получить доступ только через внутренние механизмы, такие как error_page и try_files. Откат в try_files используется только тогда, когда ни один из указанных путей не приводит к правильному файлу. Вам все еще нужно местоположение для перехвата \ .php $ URI, так как в противном случае try_files сработает на $ uri, если файл существует, и будет работать как обычный текст.
Мартин Фьордвальд
Спасибо за этот ответ ... У меня все еще есть вопрос: выполняется ли try_files сразу или будет пробоваться вложенное местоположение?
Стефан
@ Stphane Вы переезжаете в темные воды здесь. Наследование в nginx является сложным, грязным и совершенно непоследовательным. Мне пришлось просмотреть мои старые заметки, чтобы запомнить это, поэтому никаких гарантий, но кажется, что для try_files, особенно когда речь идет только о вложенных местоположениях, не будет выполняться, если внутреннее местоположение совпадает. Я бы порекомендовал проверить это, хотя.
Мартин Фьордвальд,
5

Вот еще одно удобное использование try_files в качестве безусловного перенаправления в именованные местоположения. Названные местоположения эффективно действуют как подпрограммы, сохраняя дублирование кода. Когда первый аргумент try_files - «_», всегда используется резервный редирект.

    location =/wp-login.php { try_files _ @adminlock; }
    location ^~ /wp-admin/  { try_files _ @adminlock; }
    location @adminlock  {
            allow 544.23.310.198;
            deny all;
            try_files _ @backend;
            # wp-admin traffic is tiny so ok to send all reqs to backend 
    }
    location ~ \.php {  try_files _ @backend; }
    location / { try_files $uri $uri/ =403; }
    location @backend {
            fastcgi_pass 127.0.0.1:9000;
            include snippets/fastcgi-php.conf;
    }
Крейг Хикс
источник