Условное отображение изображений с высоким разрешением и WebP с помощью nginx
Не уверен, пытаюсь ли я осуществить невозможное, но я хочу настроить Nginx для обслуживания файлов ".webp" в браузерах, которые поддерживают формат файлов, а также в качестве запасных файлов (например, pngs, jpgs и т. Д.) Для браузеров которые еще не поддерживают формат WebP. Я также хотел бы, чтобы Nginx делал все это, проверяя поддержку сетчатки и предоставляя исходные версии или версии этих фотографий размером 2x.
Пример процесса для изображения под названием "образец-фото" в /assets/img/
каталог:
- Проверьте, поддерживает ли браузер WebP и является ли оно устройством высокого разрешения, и отправьте сообщение: "assets/img/sample-photo@2x.webp".
- Устройство не может быть в высоком разрешении, поэтому вместо этого подайте: "assets/img/sample-photo.webp"
- Может быть, WebP не поддерживается, но устройство имеет высокое разрешение, так что обслуживайте: "assets/img/sample-photo@2x.png"
- Браузер не поддерживает WebP и устройство НЕ в высоком разрешении, обслуживайте: "assets/img/sample-photo.png"
Я сам попробовал это, но мне не повезло. Я нашел два удивительных сообщения, которые помогли мне начать в правильном направлении. Ниже мой код. Буду очень признателен за любые идеи и помощь в этом. Моя первая мысль, может быть, что-то шаткое происходит в последнем try_files
заявление. Спасибо!
Этот код находится в HTML-заголовке моего документа. Проверяет поддержку высокого разрешения и устанавливает cookie:
<!-- Set the 'device-pixel-ratio' cookie with Javascript if hi-res is supported -->
<script type="text/javascript">
if (!document.cookie.match(/\bdevice-pixel-ratio=/)) {
document.cookie = 'device-pixel-ratio='
+ (window.devicePixelRatio > 1 ? '2' : '1') + '; path=/';
}
</script>
<!-- A CSS-only fallback of setting the 'device-pixel-ratio' cookie just in case browsers have Javascript disabled -->
<style type="text/css">
@media only screen and (-webkit-min-device-pixel-ratio : 2),
only screen and (min-device-pixel-ratio : 2) {
head {
background-image: url(/set-device-pixel-ratio/2);
}
}
</style>
Это большая часть моего базового файла 'nginx.conf'. Оставим некоторые детали для краткости:
user www-data;
http {
##
# Basic Settings
##
sendfile on;
include /etc/nginx/mime.types;
default_type application_octet-stream;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript
##
# Conditional variables--
# Define a variable called "$webp_suffix" if the HTTP Accept header contains the "webp" substring
# and populate it with 'webp', otherwise leave empty.
##
map $http_accept $webp_suffix {
default ""
"~*webp" ".webp";
}
}
Наконец, это блок сервера, который я создал для своего сайта:
server {
listen 80;
server_name localhost;
root /var/www;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# Sets the device-pixel-ratio cookie
location ~ /set-device-pixel-ratio/(/d+)/? {
add_header Set-Cookie "device-pixel-ratio=$1;Path=/;Max-Age=31536000";
return 204; # nginx does not allow empty 200 responses
}
# Serve appropriate image assets
location ~(/assets/img/[^\.]+)(\.(?:jpg|jpeg|png|gif))$ {
# Naming convention for hi-res images:
set $hidpi_uri $1@2x$2;
if ($http_cookie !~ 'device-pixel-ratio=2') {
break;
}
try_files $hidpi_uri$webp_suffix $uri$webp_suffix $uri =404;
}
}
1 ответ
В вашем try_files
директива, вы ищите образ $uri$webp_suffix
, который разрешает image.png.webp
, Я думаю, что вы хотите посмотреть на $1$webp_suffix
там.
В противном случае, я рекомендую вам включить nginx debug_connection <your_IP>
директива в вашей основной конфигурации, и вы получите подробный журнал того, что происходит во время запроса. Там вы можете лучше увидеть, что происходит. Если вы не можете понять это, пожалуйста, добавьте журнал для запроса на вопрос, и мы можем помочь лучше.