惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
WordPress大学
WordPress大学
博客园 - 【当耐特】
The Cloudflare Blog
B
Blog
Last Week in AI
Last Week in AI
小众软件
小众软件
量子位
S
SegmentFault 最新的问题
V
Visual Studio Blog
博客园 - 叶小钗
美团技术团队
阮一峰的网络日志
阮一峰的网络日志
Hugging Face - Blog
Hugging Face - Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
宝玉的分享
宝玉的分享
A
About on SuperTechFans
雷峰网
雷峰网
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
MongoDB | Blog
MongoDB | Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Martin Fowler
Martin Fowler

kn007的个人博客

改进Nginx在支持时返回webp的逻辑 聊聊博客以及我个人近况 Nginx使用Zstd压缩传输 老歌单曲推荐:汤宝如《缘分的天空》 Fedora下关于OpenDKIM、OpenDMARC的配置实例 Fedora快速配置Postfix并挂载OpenDKIM、OpenDMARC Nginx SSL配置杂谈 服务器系统更新至Fedora Server 44 雅黑PHP探针 For PHP 8 2024年的尾巴,冒泡推歌 7月末,闲聊一些想法 MySQL 8.0.34对其自带身份验证标记弃用 怀旧粤语音乐分享 聊现今对博客的看法 聊聊对Lua Nginx Module的看法 聊聊过去一年的瞎折腾-杂项篇 聊聊过去一年的瞎折腾-电脑篇 聊聊Nginx 1.25和HTTP/3 使用acme.sh和acme-dns申请Google免费泛域名SSL证书
Nginx尝试返回webp版本的图片给浏览器
kn007 · 2026-07-09 · via kn007的个人博客

这一篇仅讨论在同时存在原始图片版本和webp版本的情况下,如何使Nginx尝试去返回webp版本给前端(比如浏览器支持webp的话),并且在不存在webp版本图片或不支持webp时回退成原始版本传递。

这种方式,主要是可以在不动目前网页代码功能上,实现自适应webp支持。

首先就是你的原始图片和webp版本(原始图片含扩展名的情况下,添加webp扩展名)在一起的情况下,直接就是代码如下。

nginx.conf的http块中:

map $http_accept $webp_suffix {
    default  "";
    "~*webp" ".webp";
}

在你的vhost中,增加:

location ~* ^/.+\.(png|jpg|jpeg)$ {
    more_set_headers "Vary: Accept";
    more_set_headers "Cache-Control: public, no-transform, max-age=2592000";
    try_files $uri$webp_suffix $uri =404;
}

这样在访问jpg、jpeg、png图时,nginx就会尝试访问webp版本,不存在时会自动降级返回。

相当于是浏览器支持时,访问的是原始图片完整名.webp,不支持时,直接就是原始图片完整名。

如果你像我一样,webp文件单独一个目录放(不污染原始目录),且只想对wordpress的uploads进行webp转换,那么可以试试以下方式。我是在wp-content新建webp目录,里面结构与uploads一致且存放为webp版本图片。

大家可以按照自己的实际来修改。

location ~* ^/wp-content/uploads/(.+\.(png|jpg|jpeg))$ {
    more_set_headers "Vary: Accept";
    more_set_headers "Cache-Control: public, no-transform, max-age=2592000";
    if ($http_accept ~* "webp") {
        rewrite ^/wp-content/uploads/(.*)$ /wp-content/webp/$1.webp last;
    }
    try_files $uri =404;
}

location ~* ^/wp-content/webp/(.+\.webp)$ {
    more_set_headers "Vary: Accept";
    more_set_headers "Cache-Control: public, no-transform, max-age=2592000";
    try_files $uri @fallback_to_original;
}

location @fallback_to_original {
    more_set_headers "Vary: Accept";
    more_set_headers "Cache-Control: public, no-transform, max-age=2592000";
    rewrite ^/wp-content/webp/(.*)\.webp$ /wp-content/uploads/$1 break;
    try_files $uri =404;
}

可能有朋友稍微懂一些的,会觉得是不是代码实现有点复杂了。但这是最好的结果,虽然单个location也能实现这个功能(包括AI也只会写一个location给你,我进行了测试),但实际上,当你的文件含非英文字符,比如中文字符,那么就会被转义,转义后,硬盘上是不存在这个文件的(除非你一开始存储就是以转义方式存储),那么Nginx就回退到原始文件,也就是含非英文字符的无法享受到webp返回。而现在这种略显复杂的实现方式,通过内部重定向逻辑来解决字符编码的问题。效率上,实际上对于Nginx几乎无影响。

另外建议大家在全局中启用open_file_cache,代码如下。这样nginx可以缓存到是否存在文件在内存中,而不用每次去硬盘查询。

还是在nginx.conf的http块中:

open_file_cache          max=100000 inactive=30s;
open_file_cache_valid    30s;
open_file_cache_min_uses 2;
open_file_cache_errors   on;

转载请注明转自: kn007的个人博客 的《Nginx尝试返回webp版本的图片给浏览器