You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js Express对接Cloudinary如何仅更新指定图片并删除冗余旧文件

实现方案

首先你需要先新增一个Cloudinary图片删除的工具函数,同时修正原有上传函数的错误处理逻辑,再调整editBlog控制器的执行顺序即可。


1. 修正并新增Cloudinary工具函数

// 修正原有上传函数的错误处理:原代码误将cloudinary返回的res当成express响应对象,会触发报错
const cloudinaryUploadImage = async image => {
  return new Promise((resolve, reject) => {
    cloudinary.uploader.upload(image , (err, res) => {
      if (err) reject(err)
      resolve({
        img_url: res.secure_url,
        img_id: res.public_id
      }); 
    })
  })
}

// 新增:Cloudinary图片删除函数
const cloudinaryDeleteImage = async (publicId) => {
  return new Promise((resolve, reject) => {
    cloudinary.uploader.destroy(publicId, (err, result) => {
      if (err) reject(err)
      resolve(result)
    })
  })
}

2. 调整editBlog控制器代码

exports.editBlog = async (req, res) => {
    const { id } = req.params;
    const { title, category, content } = req.body;
    const blogImages = req.files; 

    try {
        // 1. 先查询原博客数据,拿到旧图片ID
        const oldBlog = await Blog.findById(id);
        if (!oldBlog) {
            return res.status(404).json({ message: '博客数据不存在' });
        }

        const updates = { title, category, content };
        let oldImageIds = [];

        // 2. 有新上传图片时才处理图片替换逻辑
        if (blogImages?.length > 0) {
            // 上传新图片到Cloudinary
            const updated_images = await Promise.all(blogImages.map((img) => cloudinaryUploadImage(img.path)));
            updates.images = updated_images;
            // 收集旧图片ID,等数据库更新成功后再删除
            oldImageIds = oldBlog.images.map(img => img.img_id);
        }

        // 3. 执行数据库更新
        const updated_data = await Blog.findOneAndUpdate(
            { _id: id },
            { $set: updates },
            { new: true }
        );

        // 4. 数据库更新成功后,异步删除旧图片(不阻塞主流程,删除失败可单独打日志处理)
        if (oldImageIds.length > 0) {
            Promise.all(oldImageIds.map(id => cloudinaryDeleteImage(id)))
                .catch(err => console.log('Cloudinary旧图片删除失败:', err))
        }

        res.status(200).json({ message: '数据更新成功', result: updated_data });
    } catch (error) {
        res.status(500).json({ message: 'Internal server error', error });
    }
};

核心逻辑说明

  • 优先查询原博客数据,避免更新不存在的资源,同时拿到旧图片的public_id用于后续删除
  • 移除了原代码中无新图片就返回400的判断,支持仅修改文字内容不换图的场景
  • 数据库更新成功后再执行旧图片删除操作,避免数据库更新失败时旧图被误删,导致数据丢失
  • 旧图片删除逻辑做异步处理不阻塞主响应流程,删除失败不会影响用户正常的更新操作

内容的提问来源于stack exchange,提问作者program_bumble_bee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 03:33:04