Nginx-URL nur umschreiben, wenn Datei vorhanden ist

13

Ich muss eine Umschreiberegel für Nginx schreiben, damit, wenn ein Benutzer versucht, zu einer alten Bild-URL zu wechseln:

/images/path/to/image.png

und die Datei existiert nicht, versuche umzuleiten zu:

/website_images/path/to/image.png

NUR wenn das Bild in der neuen URL vorhanden ist, fahren Sie andernfalls mit der 404 fort. Die Version von Nginx auf unserem Host hat noch keine try_files.

Jose Fernandez
quelle

Antworten:

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

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

Möglicherweise möchten Sie jedoch Ihren Host auf Fehler überprüfen, um ein Upgrade durchzuführen oder einen besseren Host zu finden.

Martin Fjordvald
quelle
Dies wird auf jedem 404 nach / new_images umleiten, oder? Ich möchte das Neuschreiben erst durchführen, wenn ich weiß, dass die Datei new_images vorhanden ist
Jose Fernandez
Dadurch wird überprüft, ob die Datei vorhanden ist. Wenn dieser Test fehlschlägt, wird die Weiterleitung zu new_images durchgeführt. Was danach passiert, ist hier nicht spezifiziert.
Tylerl
Ich befürchte, dass Ihre Option von Nginx-
riverfall
2
@riverfall Heh, ich habe einen Teil dieser Seite geschrieben. Meine Antwort wurde vor 8 Jahren geschrieben, also ist es ein bisschen veraltet, aber in der ursprünglichen Frage stand ausdrücklich, dass der Host keine aktuelle Version von nginx zur Verfügung stellte, sodass er keinen Zugriff auf try_files hatte.
Martin Fjordvald
1
@ Guillaume86 Ich würde mir darüber keine Sorgen machen, ein if + -Rewrite ist absolut sicher und eine einzelne STAT-Prüfung einer Datei ist sehr leicht. Es ist viel schneller, als in einer Backend-Anwendung nach dem Wartungsmodus zu suchen.
Martin Fjordvald
6

Bitte nicht ifin einem Standortblock verwenden. Es können schlimme Dinge passieren.

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

$1 wird zum Dateinamen für den Versuch in der Direktive try_files, die für das vorgesehen ist, was Sie erreichen möchten.

Dies ODER, schreiben Sie es einfach um, ohne es zu überprüfen. Wenn dieses Bild nicht vorhanden ist, erhalten Sie trotzdem eine 404.

Garet Claborn
quelle
Während diese Antwort streng nicht die Frage beantworten ( „[no] try_filesnoch“), für die Besucher Zukunft kommen hier, verdient diese Antwort mehr up-Stimmen.
DerMike
5

Sie könnten so etwas verwenden (ungetestet für Ihren speziellen Fall):

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

Dies ist im Grunde eine alternative Methode, um verschachtelte ifAnweisungen zu schreiben , da Sie nicht in Nginx verschachteln können. Siehe hier für die offizielle Referenz zu diesem "Hack".

tmslnz
quelle