Nginx riscrive l'URL solo se esiste un file


13

Devo scrivere una regola di riscrittura per Nginx in modo che se un utente tenta di andare a un vecchio URL di immagine:

/images/path/to/image.png

e il file non esiste, prova a reindirizzare a:

/website_images/path/to/image.png

SOLO se l'immagine esiste nel nuovo URL, altrimenti continua con 404. La versione di Nginx sul nostro host non ha ancora try_files.

Risposte:


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

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

Tuttavia, potresti voler correggere il tuo host per aggiornare o trovare un host migliore.


Questo reindirizzerà a / new_images su ogni 404 giusto? Non voglio fare la riscrittura a meno che non sappia che esiste il file new_images
Jose Fernandez,

Questo controlla se il file esiste e se quel test fallisce, reindirizza a new_images. Quello che succede dopo non è specificato qui.
Tylerl,

Temo che la tua opzione sia considerata come insidie ​​comuni dagli autori di nginx nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/…
riverfall

2
@riverfall Heh, ho scritto parte di quella pagina. La mia risposta è stata scritta 8 anni fa, quindi sì, è un po 'datata, ma la domanda originale affermava specificamente che il loro host non forniva una versione recente di nginx, quindi non avevano accesso a try_files.
Martin Fjordvald,

1
@ Guillaume86 Non me ne preoccuperei, un if + rewrite è totalmente sicuro e un singolo controllo STAT su un file è molto leggero. È molto più veloce che passare a un'applicazione back-end per verificare la modalità di manutenzione.
Martin Fjordvald,

6

Si prega di non utilizzare ifall'interno di un blocco di posizione. Potrebbero succedere cose brutte.

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

$1 diventa il nome file da provare nella direttiva try_files, creata per quello che stai cercando di realizzare.

Questo, OPPURE, basta riscriverlo senza controllare. Se l'immagine non è presente, otterrai comunque un 404.


Sebbene questa risposta non risponda rigorosamente alla domanda ("[no] try_filesancora"), per i futuri visitatori che verranno qui, questa risposta merita più voti positivi.
DerMike,

5

Puoi usare qualcosa del genere (non testato per il tuo caso specifico):

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;
    }
}

Che è fondamentalmente un modo alternativo di scrivere ifistruzioni nidificate , poiché non è possibile nidificare in Nginx. Vedi qui per riferimento ufficiale su questo "hack".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.