Nginx reescribe URL solo si el archivo existe


13

Necesito escribir una regla de reescritura para Nginx para que si un usuario intenta ir a una url de imagen anterior:

/images/path/to/image.png

y el archivo no existe, intente redirigir a:

/website_images/path/to/image.png

SOLO si la imagen existe en la nueva URL, de lo contrario, continúe con la 404. La versión de Nginx en nuestro host todavía no tiene archivos try_files.

Respuestas:


19
location /images/ {
    if (-f $request_filename) {
        break;
    }

    rewrite ^/images/(.*) /new_images/$1 permanent;
}

Sin embargo, es posible que desee molestar a su host para actualizar o encontrar un mejor host.


Esto redirigirá a / new_images en cada 404 ¿verdad? No quiero volver a escribir a menos que sepa que existe el archivo new_images
Jose Fernandez

Esto verifica si el archivo existe, y si esa prueba falla, redirige a new_images. Lo que sucede después de eso no se especifica aquí.
tylerl

Me temo que los autores de nginx consideran que su opción es una trampa común
Nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/…

2
@riverfall Heh, escribí parte de esa página. Mi respuesta fue escrita hace 8 años, así que sí, está un poco desactualizada, pero la pregunta original sí indicaba específicamente que su host no proporcionaba una versión reciente de nginx, por lo que no tenían acceso a try_files.
Martin Fjordvald

1
@ Guillaume86 No me preocuparía por eso, una reescritura if + es totalmente segura y una sola comprobación de STAT en un archivo es muy ligera. Es mucho más rápido que ir a una aplicación de fondo para verificar el modo de mantenimiento.
Martin Fjordvald

6

No lo use ifdentro de un bloque de ubicación. Pueden pasar cosas malas.

location ~* ^/images/(.+)$ {
    root /www;
    try_files /path/to/$1 /website_images/path_to/$1 /any/dir/$1 @your404;
}

$1 se convierte en el nombre de archivo para probar en la directiva try_files, que está hecha para lo que está tratando de lograr.

Esto, O, simplemente reescríbalo sin verificar. Si esa imagen no está allí, obtendrás un 404 de todos modos.


Si bien esta respuesta estrictamente no responde la pregunta ("[no] try_filestodavía"), para los futuros visitantes que vienen aquí, esta respuesta merece más votos positivos.
DerMike

5

Podría usar algo como esto (no probado para su caso específico):

location ^/images/(?<imgpath>.*)$ {

    set $no_old  0;
    set $yes_new 0;

    if (!-f $request_filename)
    {
        set $no_old 1;
    }

    if (-f ~* "^/new_path/$imgpath")
    {
        set $yes_new 1$no_old;
    }

    # replacement exists in the new path
    if ($yes_new = 11)
    {
        rewrite ^/images/(.*)$ /new_path/$1 permanent;
    }

    # no image in the new path!
    if ($yes_new = 01)
    {
        return 404;
    }
}

Que es básicamente una forma alternativa de escribir ifdeclaraciones anidadas , ya que no puede anidar en Nginx. Ver aquí para referencia oficial sobre este "hack".

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.