Nginx本身不生成WebP,但可通过map+try_files实现零开销静态自适应;若需动态转换,须重编译启用image_filter模块并链接libwebp,或用WebP Server代理。

直接说结论:Nginx 本身不生成 WebP,但能通过 try_files + map 实现「零计算开销」的自动适配;若真要动态转,必须重编译启用 image_filter 模块并链接 libwebp,或用 WebP Server 等外部服务代理。
用 map + try_files 实现静态 WebP 自适应(推荐)
这是最轻量、最稳定的方式,前提是你的 WebP 文件已离线生成好(比如用 cwebp 批量转出),且命名规则统一。
常见错误现象:404 返回原图、浏览器支持 WebP 却始终加载 JPG/PNG、缓存错乱导致部分用户看到错格式。
-
map必须定义在http块里,不能放在server或location内,否则会报错"map directive is not allowed here" - WebP 文件路径要和原图严格对应:比如
/images/photo.jpg对应/images/photo.jpg.webp(推荐)或/images/photo.webp(需统一后缀,改名或软链) -
try_files $uri$webp_suffix $uri =404的顺序不能颠倒,否则会跳过 WebP 直接返回原图 - 务必加
add_header Vary Accept;,否则 CDN 或浏览器可能缓存错版本
示例配置片段:
http {
map $http_accept $webp_suffix {
default "";
"~*image/webp" ".webp";
}
include mime.types;
# 确保 mime.types 包含:image/webp webp;
}
<p>server {
location ~ .(jpg|jpeg|png|gif)$ {
add_header Vary Accept;
try_files $uri$webp_suffix $uri =404;
}
}启用 image_filter 动态转 WebP(需重编译)
适用于无法提前生成 WebP 文件、或需按尺寸/质量参数实时调整的场景。但性能开销明显,不建议高并发图片站直接启用。
容易踩的坑:nginx -t 通过但启动失败,大概率是 libwebp 开发包没装或路径未被 ldconfig 扫描到;image_filter_webp on 在旧版 Nginx 中不存在,仅 1.11.13+ 支持。
- CentOS 系统先运行:
yum install -y libwebp-devel;Ubuntu/Debian 用:apt install -y libwebp-dev - 宝塔用户执行
bt 16进入编译界面,在 Nginx 编译参数末尾追加:--with-http_image_filter_module --with-libwebp -
image_filter只支持 JPEG/PNG 输入,GIF/BMP 不行;输出尺寸受限于内存,默认最大 10MB 图片会触发500 - 不要在 root location 下直接用
image_filter,应单独切出一个路径(如/img-resize/)做转换入口
用 WebP Server 做旁路动态转换(免编译)
这是目前对运维最友好、兼容性最强的方案:Nginx 只做反向代理,所有转换逻辑由独立 Go 进程完成,不侵入现有配置,也不依赖 Nginx 模块。
典型问题:502 Bad Gateway(WebP Server 没启动)、图片 URL 被重写错、Safari 用户看到空图(没配 fallback)。
- WebP Server 默认监听
127.0.0.1:3333,需确认systemd服务已启用:systemctl enable --now webp-server - Nginx 配置中必须设置
proxy_set_header Accept "image/webp,*/*",否则后端无法判断协商意图 - fallback 逻辑靠 Nginx 的
proxy_next_upstream或error_page 415实现,不能只靠 WebP Server 自身配置 - 注意
IMG_PATH配置项必须指向原始图片的绝对路径(如/www/wwwroot/site.com/images),不是 URL 路径
简配示例(Nginx 端):
location ~ \.(jpg|jpeg|png|gif)$ {
proxy_pass http://127.0.0.1:3333;
proxy_set_header Host $host;
proxy_set_header Accept "image/webp,*/*";
proxy_set_header X-Real-IP $remote_addr;
proxy_intercept_errors on;
error_page 415 = @fallback;
}
location @fallback {
try_files $uri =404;
}为什么 WebP 文件总返回 text/plain?
根本原因:Nginx 没识别 .webp 后缀对应的 MIME 类型,浏览器拒绝渲染,降级为下载或空白。
这不是配置遗漏,而是 mime.types 文件本身缺失该条目,或 include mime.types 未生效。
- 检查
/etc/nginx/mime.types是否包含这一行:image/webp webp; - 若使用宝塔,该文件通常在
/www/server/nginx/conf/mime.types,手动补上即可 - 修改后必须
nginx -t && nginx -s reload,仅重启无效 - 别用
default_type image/webp全局覆盖,会导致非图片资源出错
真正麻烦的从来不是怎么配,而是 WebP 文件是否真的存在、路径是否拼对、权限是否允许 www 用户读取——这些地方一错,前面所有逻辑都白搭。


















