Перезаписати URL-адресу Nginx лише в тому випадку, якщо файл існує


13

Мені потрібно написати правило переписання для Nginx, щоб, якщо користувач намагається перейти до старої URL-адреси зображення:

/images/path/to/image.png

а файл не існує, спробуйте перенаправити на:

/website_images/path/to/image.png

ТІЛЬКИ, якщо зображення існує у новій URL-адресі, інакше продовжте 404. Версія Nginx на нашому хості ще не має try_files.

Відповіді:


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

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

Хоча, можливо, ви захочете помилитися з хостом, щоб оновити або знайти кращий хост.


Це перенаправить на / new_images на кожні 404, правильно? Я не хочу робити перезапис, якщо я не знаю, що існує файл new_images
Хосе Фернандес

Це перевіряє, чи існує файл, і якщо цей тест не вдався, він перенаправляє на new_images. Що відбувається після цього, тут не вказано.
tylerl

Я боюся, що ваш варіант розглядається як загальні підводні камені авторів nginx nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/…
водоспад

2
@riverfall Хе, я написав частину цієї сторінки. Моя відповідь була написана 8 років тому, так, так, це трохи пізніше застаріло, але в початковому запитанні було конкретно сказано, що їх хост не надав останню версію nginx, тому вони не мали доступу до try_files.
Мартін Фьордвальд

1
@ Guillaume86 Я б не хвилювався з цього приводу, якщо переписати + повністю безпечно, і одна перевірка STAT на файл дуже мала. Це набагато швидше, ніж переходити в бекенд-програму, щоб перевірити режим обслуговування.
Мартін Фьордвальд

6

Будь ласка, не використовуйте ifвсередині блоку місцезнаходження. Погані речі можуть трапитися.

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

$1 стає ім'ям файлу для спробу в директиві try_files, яка створена для того, що ви намагаєтеся виконати.

Це, АБО, просто перепишіть його, не перевіряючи. Якщо цього зображення немає, ви все одно отримаєте 404.


Хоча ця відповідь суворо не відповідає на запитання ("[поки] try_filesще немає"), для майбутніх відвідувачів, які приїдуть сюди, ця відповідь заслуговує на більшу кількість голосів.
DerMike

5

Ви можете використовувати щось подібне (не перевірено для конкретного випадку):

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

Що в основному є альтернативним способом написання вкладених ifзаяв, оскільки ви не можете вкладатись у Nginx. Дивіться тут для офіційного посилання на цей "хак".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.