Nginx通过正则location匹配缩略图URL(如/thumb/200x150/image.jpg),提取宽高与路径变量,重写并proxy_pass至Thumbor等后端服务,配合尺寸校验、缓存及安全控制实现动态代理。

在 Nginx 中实现图片缩略图的动态代理,核心是利用 location 的正则匹配识别缩略图请求(如 /thumb/200x150/image.jpg),再通过变量提取尺寸与原图路径,最后将请求反向代理到后端缩略图服务(如 Thumbor、imgproxy 或自建服务)。Nginx 本身不生成缩略图,它只做路由、重写和代理。
一、用正则 location 匹配缩略图 URL 格式
定义清晰、可扩展的 URL 规则,例如:
/thumb/{width}x{height}/{path/to/image.jpg}/resize/800w/600h/src.jpg-
/img/300x200!/{bucket}/photo.png(带裁切标记!)
推荐使用命名捕获组提升可读性。例如:
location ~ ^/thumb/(?<width>\d+)x(?<height>\d+)(?:!(?<mode>crop|fit|fill))?/(?<img path alt="Nginx 中怎么通过 location 匹配实现图片服务器的缩略图动态代理" >.+\.(?:jpg|jpeg|png|webp|gif))$ {
# 后续处理
}注意:location ~ 是区分大小写的正则匹配;若需忽略大小写,用 ~*;确保该 location 在通用静态文件 location 之前,避免被提前命中。
二、提取参数并重写为后端服务可识别的格式
利用 $width、$height、$imgpath 等捕获变量,拼接目标后端地址。例如后端是 http://thumbor:8000,其标准格式为 http://thumbor/unsafe/{width}x{height}/source_url:
set $src_url "https://origin.example.com/$imgpath";
proxy_set_header X-Original-URL $src_url;
proxy_pass http://thumbor:8000/unsafe/${width}x${height}/$src_url;
或者对接更简洁的 imgproxy,其格式为:/rs:fill:${width}:${height}:/path/to/image:
proxy_pass http://imgproxy:8080/rs:fill:${width}:${height}:/https://origin.example.com/$imgpath;
关键点:
– 使用 set 指令预定义变量,避免在 proxy_pass 中直接拼接出错;
– 原图 URL 必须可被后端访问(公网或内网互通);
– 若源站有鉴权(如私有 bucket),需在 proxy_set_header 中透传 token 或签名头。
三、添加缓存与安全控制
缩略图属于可缓存资源,应在 Nginx 层配置合理缓存策略:
expires 7d; add_header Cache-Control "public, immutable"; proxy_cache_valid 200 302 30d; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
同时限制非法尺寸或恶意请求:
- 用
if ($width > 4096) { return 400; }防超大尺寸耗尽内存 - 用
valid_referers或 IP 白名单限制盗链(可选) - 拒绝非图片后缀请求:
if ($imgpath !~ \.(jpe?g|png|webp|gif)$) { return 403; }
四、完整示例配置(Thumbor 后端)
upstream thumbor_backend {
server 10.0.1.10:8000;
}
<p>server {
listen 80;
server_name img.example.com;</p><pre class="brush:php;toolbar:false;"># 缩略图动态代理
location ~ ^/thumb/(?<width>\d+)x(?<height>\d+)(?:!(?<mode>crop|fit))?(?:/(?<imgpath>[^?]+))?$ {
# 尺寸限制
if ($width > 3840) { return 400; }
if ($height > 2160) { return 400; }
# 构造源图 URL(假设原始图在 s3.example.com)
set $origin_host "https://s3.example.com";
set $full_src "$origin_host/$imgpath";
# 传递给 Thumbor:/unsafe/200x150/filters:quality(85):format(webp)/$full_src
proxy_set_header Host thumbor.example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://thumbor_backend/unsafe/${width}x${height}/filters:quality(85):format(webp)/$full_src;
# 缓存
proxy_cache thumbor_cache;
proxy_cache_valid 200 302 7d;
expires 7d;
add_header X-Thumbor-Cached $upstream_http_x_cache;
}
# 默认返回 404(禁止直接访问原图)
location / {
return 404;
}}
注:需提前定义 proxy_cache_path 和缓存区,并确保 $imgpath 不含恶意路径遍历(Nginx 正则已限定格式,一般无需额外 decode)。


















