Всем привет!
У меня есть вопрос по реализации одной идеи. На сервере хранятся файлы с расширениями .jpeg и .gif. В случаях, когда запрашивается файл .gif, вместо него выводится .jpeg-заглушка. Однако, когда запрос идет напрямую на оригинальный файл .jpeg, возникает проблема с отсутствием этого файла.
В конфигурации Nginx у меня прописан следующий блок location:
<pre><code>location @original {
try_files $image_folder_1$uri $image_folder_0$uri @errors;
}</code></pre>
Проблема в том, что когда файл запрашивают с правильным расширением .jpeg, все работает как надо. Но для некоторых файлов есть расширение .gif, и если происходит запрос на file.jpeg, то этого файла нет, хотя существует file.gif.
Я хочу добавить в этот блок location дополнительную проверку на наличие файла .gif на основании запроса к .jpeg. Если файл .gif существует, нужно сделать редирект 301 с file.jpeg на file.gif. Если же .gif отсутствует, перенаправить на @errors.
Либо, в крайнем случае, я хотел бы отобразить содержимое file.gif по ссылке на file.jpeg.
Если рассматривать частичное использование JavaScript, это могло бы выглядеть так:
<pre><code>location @original {
try_files $image_folder_1$uri $image_folder_0$uri $image_folder_1$uri.replace(".jpeg", ".gif") $image_folder_0$uri.replace(".jpeg", ".gif") @errors;
}</code></pre>
Как мне лучше организовать эту логику в Nginx?
В Nginx вы не можете использовать JavaScript для обработки логики, такой как замена строк, в директиве `try_files`. Вместо этого вы можете использовать несколько блоков `location` и директиву `if` для достижения желаемого поведения.
Что касается вашей задачи, мы можем организовать это следующим образом:
1. Первым делом проверяем, существует ли файл с окончанием `.jpeg`.
2. Если существует, то проверяем, существует ли файл с окончанием `.gif`.
3. Если файл `.gif` существует, выполняем редирект на него; если нет - отправляем на обработку ошибки.
Вот пример конфигурации:
```nginx
server {
...
location /images/ {
# Путь к файлам
set $image_folder_0 /path/to/your/images/0/;
set $image_folder_1 /path/to/your/images/1/;
# Обрабатываем запрос .jpeg
location ~ \.jpeg$ {
set $uri_gif $uri;
# Меняем расширение с .jpeg на .gif
if (-f $image_folder_1$uri_gif) {
set $uri_gif $uri_gif;
}
if (-f $image_folder_0$uri_gif) {
set $uri_gif $uri_gif;
}
if ($uri_gif ~* \.jpeg$) {
# Смотрим, существует ли .gif
set $uri_gif ${uri_gif/.jpeg/.gif};
if (-f $image_folder_1$uri_gif) {
return 301 $uri_gif;
}
if (-f $image_folder_0$uri_gif) {
return 301 $uri_gif;
}
}
# Если .gif не найден, отправляем на @errors
return 404;
}
# Обрабатываем запрос .gif
location ~ \.gif$ {
try_files $image_folder_1$uri $image_folder_0$uri =404;
}
# Для остальных файлов используем общемасштабный блок
location / {
try_files $image_folder_1$uri $image_folder_0$uri =404;
}
}
location @errors {
# Обработка ошибок
...
}
}
```
В этом примере:
- Мы определяем отдельные блоки для обработки `.jpeg` и `.gif`.
- Внутри блока для `.jpeg` мы проверяем, существует ли файл с соответствующим расширением `.gif` и выполняем редирект 301, если он существует.
- Если файл с расширением `.gif` не найден, возвращаем 404 (либо перенаправляем на `@errors`, если вам это нужно).
- Блоки `location` могут быть настроены в зависимости от вашего пути к изображениями.
Это не идеальное решение, так как использование `if` в конфигурации Nginx может быть ненадежным и неэффективным. Тем не менее, это наиболее простой и понятный способ достичь требуемой функциональности в данном случае.
Или хотя бы отобразить по ссылке на file.jpeg, сам file.gif
Создать новую переменную и заменить .jpeg на .gif с помощью map .
map $uri $gif { default $uri; ~^(.*)\.jpeg$ "$1.gif"; } server { location @original { try_files $image_folder_1$uri $image_folder_0$uri $image_folder_1$gif $image_folder_0$gif @errors; }