使用 nginx 有条件地提供高分辨率和 WebP 图像

使用 nginx 有条件地提供高分辨率和 WebP 图像

不确定我是否在尝试完成不可能的任务,但我想配置 Nginx,以便为支持该文件格式的浏览器提供“.webp”文件,并为尚不支持 WebP 格式的浏览器提供后备文件(即 png、jpg 等)。我还希望 Nginx 在检查视网膜支持并提供这些照片的原始版本或 @2x 大小版本的同时完成所有这些工作。

目录中名为“sample-photo”的图像的示例处理过程/assets/img/

  • 检查浏览器是否支持 WebP,并且如果它是高分辨率设备,则提供:“assets/img/[电子邮件保护]
  • 设备可能不是高分辨率的,因此改为提供:“assets/img/sample-photo.webp”
  • 可能不支持 WebP,但设备分辨率较高,因此提供:“assets/img/[电子邮件保护]
  • 浏览器不支持 WebP 且设备不是高分辨率,请提供:“assets/img/sample-photo.png”

我自己也尝试过,但运气不佳。我发现了两篇很棒的帖子,它们帮助我朝着正确的方向前进。下面是我的代码。非常感谢任何关于这方面的见解和帮助。我的第一个想法是,也许最后一条try_files语句出了点问题。非常感谢!

  1. 有条件地提供高分辨率图像
  2. 使用 nginx 有条件地提供文件服务

此代码位于我的文档的 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

否则,我建议您在主配置中启用 nginxdebug_connection <your_IP>指令,这样您将获得请求期间发生情况的详细日志。在那里您可以更好地了解发生了什么。如果您无法弄清楚,请将请求的日志添加到问题中,我们可以更好地提供帮助。

相关内容