MERN应用中sharp中间件内req未定义,后续控制器正常的问题求助
问题分析与解决方案
核心问题梳理
你遇到的异常来自三个关键问题:
- 路由中的拼写错误
- 中间件顺序颠倒
- Multer存储配置与图片处理逻辑不兼容
1. 修复路由拼写错误
你的/new路由里把convertToWebP误写为converToWebP,导致中间件未被正确加载,直接引发req相关异常:
// 错误写法 router.post("/new", isLoggedIn, converToWebP, upload.array("images"), createCountry); // 正确写法 router.post("/new", isLoggedIn, upload.array("images"), convertToWebP, createCountry);
2. 调整中间件顺序
convertToWebP依赖Multer解析后的req.files,必须把upload.array("images")放在convertToWebP之前,否则中间件里根本拿不到文件数据。
3. 修改Multer存储配置
你当前使用Cloudinary直接存储,这种模式下Multer会直接把文件上传到Cloudinary,不会在req.files中保留buffer,导致Sharp无法读取文件内容。需要改成内存存储,先把文件存在内存中处理,再上传到Cloudinary:
// 替换原有upload配置 const storage = multer.memoryStorage(); // 用内存存储替代Cloudinary直接存储 const upload = multer({ storage: storage });
4. 重写convertToWebP中间件
文件存在内存buffer后,转成WebP格式再手动上传到Cloudinary,最后构造符合控制器预期的文件对象:
const sharp = require("sharp"); const { cloudinary } = require("../imageupload/cloudinary"); exports.convertToWebP = async (req, res, next) => { try { req.files = await Promise.all(req.files.map(async (file) => { // 将文件转换为WebP格式 const webpBuffer = await sharp(file.buffer) .toFormat('webp') .toBuffer(); // 上传处理后的WebP到Cloudinary const uploadResult = await new Promise((resolve, reject) => { cloudinary.uploader.upload_stream( { resource_type: "image", format: "webp" }, (error, result) => { if (error) reject(error); resolve(result); } ).end(webpBuffer); }); // 返回控制器需要的文件结构 return { path: uploadResult.secure_url, filename: uploadResult.public_id, originalname: `${file.originalname}.webp` }; })); next(); } catch (error) { res.status(500).json({ message: error.message }); } };
5. 确保Body解析中间件已加载
在Express主文件中,必须在挂载路由前加载Body解析中间件,否则req.body会为空:
const express = require("express"); const app = express(); // 必须放在路由挂载之前 app.use(express.json()); app.use(express.urlencoded({ extended: true })); // 挂载路由 app.use("/countries", require("./routes/country"));
内容的提问来源于stack exchange,提问作者Isaiahm
相关产品推荐
相关产品推荐

