Express中用Sharp缩放图片后上传Cloudinary,图片未缩放问题求助
问题分析与解决方案
核心问题1:Cloudinary上传中间件提前完成上传
你使用的upload.single("photo")(推测是multer-storage-cloudinary提供的中间件)会自动将接收的图片直接上传到Cloudinary,导致后续用Sharp处理后再调用upload_stream的操作完全无效——中间件已经把原始尺寸的图片上传,甚至会因为public_id相同,覆盖你后面上传的缩放后图片。
核心问题2:异步逻辑与响应错误
代码中存在两处res.status(200)响应,且upload_stream是基于回调的API,不能用await修饰,这会导致回调尚未执行完成就提前发送响应,逻辑混乱。
修正后的代码
调整流程为:接收原始图片→Sharp缩放→上传到Cloudinary,改用multer内存存储接收文件,避免提前上传:
const express = require("express"); const router = express.Router(); const multer = require("multer"); const sharp = require("sharp"); const cloudinary = require("cloudinary").v2; // 用multer内存存储接收原始文件,不提前上传到Cloudinary const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); router.post("/", upload.single("photo"), async (req, res) => { try { if (!req.file) { return res.status(400).json({ message: "No file uploaded" }); } // Sharp缩放图片 const resizedImageBuffer = await sharp(req.file.buffer) .resize({ width: 150, height: 150, fit: sharp.fit.inside, withoutEnlargement: true, }) .toBuffer(); // 用Promise封装upload_stream,适配async/await逻辑 const uploadResult = await new Promise((resolve, reject) => { cloudinary.v2.uploader.upload_stream( { resource_type: "image", folder: "user_profiles", public_id: req.file.originalname, overwrite: true, }, (error, result) => { if (error) reject(error); else resolve(result); } ).end(resizedImageBuffer); }); res.status(200).json({ message: "Photo uploaded and resized successfully", result: uploadResult, }); } catch (error) { console.error("Error:", error.message); console.error(error.stack); res.status(500).json({ message: "Error uploading and resizing the photo", error: error.message, }); } }); module.exports = router;
关键修改说明
- 替换Cloudinary上传中间件,改用
multer.memoryStorage()在内存中暂存原始文件,避免提前上传。 - 用Promise封装
upload_stream,解决回调与async/await混用的异步逻辑问题。 - 移除重复响应语句,确保仅在上传完成后发送一次响应。
- 添加文件存在性检查,处理未上传文件的边界情况。
内容的提问来源于stack exchange,提问作者JohnM
相关产品推荐
相关产品推荐

