Nginx перезаписывает URL, только если файл существует

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/…
riverfall
2
@ riverfall Хех, я написал часть этой страницы. Мой ответ был написан 8 лет назад, так что да, он немного устарел, но в первоначальном вопросе было указано, что его хост не предоставил последнюю версию nginx, поэтому у них не было доступа к try_files.
Мартин Фьордвальд,
1
@ Guillaume86 Я бы не беспокоился об этом, перезапись if + абсолютно безопасна, а одна проверка 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. Смотрите здесь для официальной ссылки на этот "взломать".

tmslnz
источник