宝塔「开启webp」开关无效,因未手动添加map规则、vary头、try_files逻辑及mime类型声明;nginx需在http块内配置map $http_accept $webp_suffix识别accept头,并通过try_files优先返回同名.webp文件,同时添加add_header vary accept确保缓存正确,且types中声明image/webp webp。

宝塔面板默认不识别 WebP,也不会自动根据浏览器能力返回对应格式图片——必须手动补全 map 规则、Vary 响应头、try_files 路由逻辑和 MIME 类型声明,缺一不可。
为什么「开启 WebP」开关没用?
宝塔后台的「开启 WebP」选项只是 UI 占位符,不写入任何 Nginx 配置。Nginx 根本收不到 Accept: image/webp 判断依据,自然不会尝试返回 .webp 文件。
- 常见现象:Chrome DevTools Network 里图片仍是
Content-Type: image/jpeg,没有.webp响应 - 根本原因:缺少
map $http_accept $webp_suffix { ... }这一行,Nginx 无法把请求头映射成后缀变量 - 位置错误也会导致 500:该
map必须放在http块内(即所有server外),不能塞进server或location里
如何配置 Nginx 自动匹配 .webp 文件?
核心是用 try_files 实现「先找 xxx.jpg.webp → 找不到就回退 xxx.jpg」,不依赖实时转码,零 CPU 开销。
- 在站点【配置文件】的
server块顶部插入:map $http_accept $webp_suffix { default ""; "~*webp" ".webp"; } - 在
location ~ .*\.(jpg|jpeg|png|gif)$ {块内,替换或添加:add_header Vary Accept; try_files $uri$webp_suffix $uri =404;
-
add_header Vary Accept必须加:否则 CDN 或代理会缓存错版本,同一 URL 可能对 Chrome 返回 .webp、对 Safari 返回 .jpg - 确保 WebP 文件已存在且命名正确:比如
/images/banner.jpg对应/images/banner.jpg.webp(不是banner.webp)
为什么图片显示空白或被浏览器拦截?
浏览器报 The resource was blocked due to MIME type mismatch,说明 Nginx 返回了 .webp 文件但没声明正确类型。
- 进入【软件商店】→ Nginx 【设置】→ 【配置修改】,在
http块内确认有:types { image/webp webp; } - 如果用了 CDN,请检查是否透传
Accept头(Cloudflare 默认不透传,需在 Page Rule 中开启「Cache Level: Bypass」或自定义缓存键) - Safari 仅支持 WebP 从 iOS 14 / macOS 11.0 起,旧版 Safari 会收到 .jpg 回退,但若 MIME 错误仍可能白屏
要不要编译 image_filter 或 pagespeed 模块?
除非你明确需要运行时缩放+转 WebP(比如用户上传原图后动态生成不同尺寸 WebP),否则没必要。预生成 + try_files 更快、更稳、不占 CPU。
-
ngx_http_image_filter_module不支持直接输出 WebP,必须重新编译 Nginx 并链接libwebp,过程易出错 -
ngx_pagespeed会自动转图,但吃内存、难调试,且对 PHP 输出的图片(如 GD 生成的验证码)无效 - 批量转 WebP 推荐用
cwebp:find /www/wwwroot/your-site -name "*.jpg" -exec cwebp {} -q 80 -o {}.webp \;再用rename 's/\.jpg\.webp$/.webp/' *.webp修正后缀(注意路径权限)
最容易被忽略的是 Vary Accept 和文件命名一致性:CDN 缓存策略和 Nginx 文件查找逻辑都依赖这两点,错一个,WebP 就只对部分用户生效。











