¿Cómo funciona try_files?

72

Miré la documentación de nginx y todavía me confunde por completo.

Como try_filesfunciona Esto es lo que dice la documentación:

De NginxHttpCoreModule

try_files

sintaxis: try_files ruta1 [ruta2] uri

predeterminado: ninguno

contexto: servidor, ubicación

disponibilidad: 0.7.27

Comprueba la existencia de archivos en orden y devuelve el primer archivo que se encuentra. Una barra inclinada final indica un directorio: $ uri /. En el caso de que no se encuentre ningún archivo, se invoca una redirección interna al último parámetro. El último parámetro es el URI de reserva y debe existir, de lo contrario, se generará un error interno. A diferencia de la reescritura, $ args no se conservan automáticamente si el respaldo no es una ubicación con nombre. Si necesita preservar args, debe hacerlo explícitamente:

No entiendo cómo comprueba las rutas y qué pasa si no quiero un error interno, pero ¿debo reanudar el resto de la ruta en un esfuerzo por encontrar otro archivo?

Si quiero probar un archivo en caché /path/app/cache/url/index.htmly si no lo intenta, /path/app/index.php¿cómo escribiría eso? Si yo escribiera:

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;

Tengo index index.php index.html index.htm;. Cuando visito /urlname, ¿se trata de leer /path/app/cache/urlname/index.phpa continuación /path/app/cache/urlname/index.html? Si ignoramos todo después, ¿ try_fileses posible try_filesverificar la carpeta de caché? He estado intentando y he fallado.

76484
fuente

Respuestas:

64

try_files intenta la ruta literal que especifique en relación con la directiva raíz definida y establece el puntero interno del archivo. Si usa, por ejemplo, try_files /app/cache/ $uri @fallback;con index index.php index.html;, probará las rutas en este orden:

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

antes de finalmente redirigir internamente a la ubicación con nombre @fallback. También puede usar un archivo o un código de estado ( =404) como su último parámetro, pero si usa un archivo, debe existir .

Debe tener en cuenta que try_files en sí no emitirá una redirección interna para nada más que el último parámetro. Lo que significa que no puede hacer lo siguiente: try_files $uri /cache.php @fallback;ya que eso hará que nginx establezca el puntero interno del archivo en $ document_root / cache.php y lo sirva, pero como no se realiza una redirección interna, las ubicaciones no se vuelven a evaluar y, como tal, será sirvió como texto sin formato. (La razón funciona con archivos PHP como el índice es que la directiva índice se emitirá un redireccionamiento interno)

Martin Fjordvald
fuente
2
Eso está MUCHO más claro. Gracias. No estoy seguro de cómo funciona la ubicación con nombre. Si @fallback tiene líneas para fastcgi php que lo servirían como un archivo php en lugar de texto? ¿Se usa la reserva cuando todo antes de que falle?
2
Una ubicación con nombre es funcionalmente idéntica a una ubicación normal, excepto que solo se puede acceder a través de mecanismos internos como error_page y try_files. El respaldo en try_files solo se usa cuando ninguna de las rutas especificadas da como resultado un archivo válido. Todavía necesita una ubicación para capturar \ .php $ URI ya que, de lo contrario, try_files se activará en $ uri si el archivo existe y lo servirá como texto sin formato.
Martin Fjordvald
Gracias por esta respuesta. Todavía tengo una pregunta aquí: ¿Se ejecutan try_files de inmediato o se intentará la ubicación anidada antes?
Stphane
@Stphane Te estás mudando a aguas turbias aquí. La herencia en nginx es compleja, desordenada y totalmente inconsistente. Tuve que revisar mis notas anteriores solo para recordar esto, así que no hay garantías, pero parece que para try_files, específicamente cuando se trata solo de ubicaciones anidadas, no se ejecutará si la ubicación interna coincide. Sin embargo, recomendaría probarlo.
Martin Fjordvald
5

Aquí hay otro uso conveniente de try_files, como redireccionamientos incondicionales a ubicaciones con nombre. Las ubicaciones nombradas actúan efectivamente como subrutinas, ahorrando duplicación de código. Cuando el primer argumento para try_files es "_", siempre se toma la redirección alternativa.

    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;
    }
Craig Hicks
fuente