nginx通过map解析accept头判断webp支持,再用try_files按$uri.webp→$uri顺序匹配预生成文件,配合vary accept头与差异化缓存策略实现无损自动适配。

Nginx 本身不生成 WebP,但能根据浏览器的 Accept 请求头和本地文件存在情况,自动返回 .webp 或原图——前提是 WebP 文件已离线生成好,且路径/命名规则对得上。
WebP 自动适配依赖两个核心判断
必须同时满足:① 请求头带 image/webp;② 对应的 .webp 文件真实存在。缺一不可,否则会 fallback 到原图。
-
map指令用于解析$http_accept,生成布尔型变量(如$webp_supported),注意正则要加~*表示忽略大小写 -
try_files是关键分发逻辑:它按顺序检查文件是否存在,try_files $uri.webp $uri =404这种写法只适用于/img/photo.jpg→ 查找/img/photo.jpg.webp - 若你用的是统一后缀(如
/img/photo.jpg→/img/photo.webp),就得改用rewrite或重命名脚本预处理,try_files无法跨扩展名匹配
map + try_files 配置必须放在 server 块顶层
很多人把 map 写在 location 里,Nginx 会直接报错:"map" directive is not allowed here。它只能出现在 http 或 server 上下文(推荐放 http 块,全局复用)。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 正确位置示例:
http { map $http_accept $webp_ext { ~*webp ".webp"; default ""; } server { ... } } -
try_files必须放在匹配图片的location ~* \.(jpg|jpeg|png|gif)$块内,且不能和root/alias冲突——如果用了alias,$uri不含前缀路径,$uri.webp就会拼错 - 常见错误:配置完发现始终返回原图。先
curl -H "Accept: image/webp" -I http://localhost/test.jpg看响应头是否含Content-Type: image/webp,再确认ls /path/to/test.jpg.webp是否真存在
Vary: Accept 头和缓存策略必须配套
CDN 或浏览器看到相同 URL(如 /logo.png)可能缓存了原图,下次即使支持 WebP 也拿不到。必须显式告诉中间层:“这个 URL 的响应内容取决于 Accept 头”。
- 加
add_header Vary Accept;到图片location块里,否则缓存系统会认为所有请求都该返回同一份内容 - WebP 文件体积小、更新频率低,适合长缓存;原图相对大、可能更常更新,缓存时间应更短。用
map动态设置Cache-Control:
map $sent_http_content_type $cache_max_age {
~*image/webp "max-age=31536000";
default "max-age=86400";
}
location ~* \.(jpg|jpeg|png|gif)$ {
add_header Vary Accept;
expires $cache_max_age;
}
WebP 文件怎么批量生成并命名才不踩坑
别手动一张张转。用 cwebp 批量生成时,命名方式直接决定 Nginx 配置复杂度。
- 最省事方案:保持原路径+原名+
.webp后缀,即/static/a.png→/static/a.png.webp。这样try_files $uri.webp $uri能直接工作 - 若想用
.webp作唯一后缀(如/static/a.webp),就得用rewrite提取文件名再替换后缀,或用 shell 脚本批量重命名:for i in *.png; do cwebp "$i" -o "${i%.png}.webp"; done - 注意权限:生成的
.webp文件需和原图有相同读权限,Nginx worker 进程用户(如www-data)必须能读取它们,否则try_files会静默跳过
真正容易被忽略的是 Vary: Accept 和文件权限这两处。前者导致缓存污染,后者让整个协商逻辑静默失效——查日志也看不到错误,只会一直返回原图。










