基于查询字符串实现图片自动缩放(Node.js)
Express 图片按需缩放实现方案
核心依赖选择
直接用sharp,这是Node.js生态里最适合服务器场景的图片处理库——基于libvips底层,性能碾压纯JS实现的库,内存占用低,支持JPG/PNG/WebP等几乎所有主流格式,缩放、裁剪、压缩一站式搞定。
具体实现步骤
安装依赖
npm install sharp路由拦截与参数处理
给Express加一个路由,拦截图片请求,解析w和h参数:- 先验证参数合法性:必须是正整数,且限制最大宽高(比如2000px),避免恶意请求拖垮服务器
- 找不到参数或参数非法时,返回原图
图片处理与缓存
- 处理前先检查本地缓存目录(比如
./public/cache)有没有对应尺寸的图片,有就直接返回 - 没有的话读取源图片,用sharp缩放,然后保存到缓存目录,再返回给客户端
- 处理前先检查本地缓存目录(比如
完整示例代码
const express = require('express'); const sharp = require('sharp'); const fs = require('fs').promises; const path = require('path'); const app = express(); const PORT = 3000; const IMAGE_DIR = path.join(__dirname, 'public'); const CACHE_DIR = path.join(__dirname, 'public/cache'); // 确保缓存目录存在 fs.mkdir(CACHE_DIR, { recursive: true }).catch(err => console.error(err)); // 拦截图片请求 app.get(/\.(jpg|jpeg|png|webp)$/, async (req, res) => { const { w, h } = req.query; const imagePath = path.join(IMAGE_DIR, req.path); // 验证参数:必须是正整数,且不超过2000px const width = w ? parseInt(w) : null; const height = h ? parseInt(h) : null; const isValidSize = width && height && width > 0 && height > 0 && width <= 2000 && height <= 2000; // 无合法参数时返回原图 if (!isValidSize) { return res.sendFile(imagePath); } // 生成缓存文件名 const cacheFileName = `${path.basename(req.path, path.extname(req.path))}_${w}x${h}${path.extname(req.path)}`; const cachePath = path.join(CACHE_DIR, cacheFileName); try { // 检查缓存是否存在 await fs.access(cachePath); return res.sendFile(cachePath); } catch { // 缓存不存在,处理图片 try { await sharp(imagePath) .resize(width, height, { fit: 'cover', // 可选:cover/contain/fill等,按需选择 withoutEnlargement: true // 避免放大原图 }) .toFile(cachePath); return res.sendFile(cachePath); } catch (err) { console.error('图片处理失败:', err); res.status(500).send('图片处理失败'); } } }); app.listen(PORT, () => { console.log(`服务器运行在端口 ${PORT}`); });
优化建议
- 缓存策略:可以给缓存文件设置过期时间,定期清理旧缓存;或者用Redis缓存处理后的图片Buffer,减少磁盘IO
- 格式优化:自动将图片转换为WebP格式(比JPG/PNG小30%-50%),只需在sharp调用里加
.webp() - 防盗链:检查请求的Referer头,只允许来自你的域名的请求
- 限流:给图片处理接口加限流,避免单IP发起大量请求
内容的提问来源于stack exchange,提问作者vanminhquangtri
相关产品推荐
相关产品推荐

