Node.js中如何将Cloudinary上传的图片URL存储到MongoDB
问题根因
cloudinary.uploader.upload 是异步非阻塞方法,传入的回调函数会在上传流程全部完成后才触发,回调外的同步代码不会等待上传执行完毕,会直接按顺序运行,因此在外层读取cloudinaryUrl时,变量还没被回调内的逻辑赋值,永远是空字符串。
解决方案
两种可落地的实现方式:
- 方案1:将数据库存储逻辑移入上传回调内,确保拿到有效URL后再执行存库操作
app.post('/api/amin/create', (req, res) => { req.body.adminId = Math.floor(10 + Math.random() * 100); cloudinary.uploader.upload(req.body.coverPhotoFile, function(error, result) { // 先处理上传错误 if (error) { return res.status(500).json({ msg: '图片上传失败' }) } req.body.photoUrl = result.url // 此处编写MongoDB数据插入逻辑,拿到返回结果后再给前端返回响应 }) })
- 方案2:使用
async/await改写为同步写法(推荐,避免回调嵌套,代码逻辑更清晰)
Cloudinary的上传方法原生支持Promise返回,配合async/await可以让代码按书写顺序执行:
app.post('/api/amin/create', async (req, res) => { try { req.body.adminId = Math.floor(10 + Math.random() * 100); // 等待上传完成拿到结果,再执行后续逻辑 const uploadRes = await cloudinary.uploader.upload(req.body.coverPhotoFile) req.body.photoUrl = uploadRes.url // 此处直接编写MongoDB存储逻辑即可,此时photoUrl已经是Cloudinary返回的有效地址 // 存储完成后正常给前端返回响应 } catch (err) { res.status(500).json({ msg: '操作失败' }) } })
注意:所有依赖Cloudinary上传返回结果的逻辑,必须放在异步回调内,或者await等待上传完成后再执行,不要在异步调用外部直接读取异步流程内的赋值。
内容的提问来源于stack exchange,提问作者Michael Chinye
相关产品推荐
相关产品推荐

