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

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
Y
Y Combinator Blog
博客园 - 【当耐特】
V
Visual Studio Blog
GbyAI
GbyAI
V
V2EX
P
Proofpoint News Feed
Microsoft Azure Blog
Microsoft Azure Blog
Microsoft Security Blog
Microsoft Security Blog
D
DataBreaches.Net
Hugging Face - Blog
Hugging Face - Blog
A
About on SuperTechFans
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
N
Netflix TechBlog - Medium
aimingoo的专栏
aimingoo的专栏
B
Blog RSS Feed
量子位
MongoDB | Blog
MongoDB | Blog
有赞技术团队
有赞技术团队
人人都是产品经理
人人都是产品经理
Stack Overflow Blog
Stack Overflow Blog
小众软件
小众软件

kn007的个人博客

聊聊博客以及我个人近况 Nginx使用Zstd压缩传输 Nginx尝试返回webp版本的图片给浏览器 老歌单曲推荐:汤宝如《缘分的天空》 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-27 · via kn007的个人博客

前情提要详见文章《Nginx尝试返回webp版本的图片给浏览器》。

在文章中,我提到了多个location是为了rewrite会转义导致非英文名文件,字符转义后,实际找不到硬盘文件(硬盘文件存储是未转义前的名字),所以使用了多个location的方式来解决。

虽然多个location实际对nginx来说也没什么太多的性能影响,但里面还有rewrite,我一直对rewrite的性能有偏见,但是用正常逻辑做出来的不需要rewrite的正则,nginx总不能正常匹配。

后面查阅文章后,发现是Nginx的变量覆盖问题(惰性求值与全局正则覆盖),导致正则匹配后的结果(如$1、$2这种),会因为其他变量被覆盖或执行前匹配了。

而这个问题,可以通过正则的命名捕获组来解决,那最终我们可以不使用rewrite且一个location来解决我们这个需求,加上对非必要的匹配使用了非捕获组,更加节省性能(对比之前文章的方法也算是质的飞跃了)。

目前解决后,我们的实现方法如下,在nginx.conf的http块中定义:

map $http_accept $webp_prefix {
default "";
"~*webp" "webp/";
}

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

在你的vhost中,使用:

location ~* ^/wp-content/(?<folder>thumbnails|uploads)/(?<img_path>.+\.(?:png|jpg|jpeg))$ {
more_set_headers "Vary: Accept";
more_set_headers "Cache-Control: public, no-transform, max-age=2592000";
try_files /wp-content/$webp_prefix$folder/$img_path$webp_suffix $uri =404;
}

这样便可以实现请求wp-content目录下的thumbnails和uploads目录,在浏览器支持的情况下,尝试去wp-content/webp目录下的thumbnails和uploads目录寻找webp文件并返回;如果不存在对应webp文件,会在原始位置调用源文件返回(由$uri保障)。在浏览器不支持的情况下,第一个实际匹配的就是原始位置,即便有意外,也有$uri兜底。如果都不存在,调用404。

另外可以通过以下配置对webp文件,进行缓存过期设置:

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

其他注意和建议事项,见之前文章《Nginx尝试返回webp版本的图片给浏览器》,不再赘述。

这篇文章也算是个记录,提醒自己只要在正则相关配置中引入了map、rewrite等可能涉及变量覆写的,就应当抛弃$1和$2这种传统方式,改用(?<name>...)命名捕获组来实现需求。

转载请注明转自: kn007的个人博客 的《改进Nginx在支持时返回webp的逻辑