MERN栈仅更新标题描述时出现Cloudinary图片404错误
问题描述
在MERN栈项目中仅更新文章的title和description字段时,出现图片未找到错误,具体错误信息如下:
博客文章错误:{
message: '资源未找到 - https://res.cloudinary.com/cloud_name/image/upload/v1700847934/blog-mern-app/kzg1lxdqfnt2asls0mgq.jpg',
name: 'Error',
http_code: 404
}
创建文章控制器代码
const createPostController = async (req, res) => { try { const { title, description, image } = req.body; if(!title){ return res.status(400).json({message:"invalid title"}); } if(!description){ return res.status(400).json({message:"invalid description"}); } if(!image){ return res.status(400).json({message:"invalid image"}); } const uploadPhoto = await cloudinary.uploader.upload(image, { folder: "blog-mern-app" }); const createPost = new Post({ title, description, image: { public_id: uploadPhoto.public_id, url: uploadPhoto.secure_url } }); await createPost.save(); res.status(201).json({success:true, message:"post created successully", createPost}); } catch (error) { res.status(500).json({success:false, message: "Error Creating The Blog post"}) } }
更新文章控制器代码
const updatePostController = async (req, res) => { try { const { title, description, image } = req.body; const currentPost = await Post.findById(req.params.id); if (!currentPost) { return res.status(404).json({ message: "Post not found" }); } if(!image){ return res.status(404).json({message:"image is compulsary"}); } if (image) { if (currentPost.image) { const currentImgId = currentPost.image.public_id; await cloudinary.uploader.destroy(currentImgId); } const uploadNewImg = await cloudinary.uploader.upload(image, { folder: "blog-mern-app" }); currentPost.image = {public_id:uploadNewImg.public_id, url:uploadNewImg.secure_url}; } currentPost.title = title; currentPost.description = description; await currentPost.save(); res.status(201).json({ success:true, message:"updated post successfully", currentPost}); } catch (error) { console.error("error in blog post:", error); res.status(500).json({success:false, message: "error in updating blog post", error:error.message }); } }
错误原因分析
- 强制要求图片参数:更新控制器中存在
if(!image){return res.status(404).json({message:"image is compulsary"});}的判断,导致仅更新文本字段时必须传入image参数,不符合实际需求。 - 无效图片上传逻辑:如果前端为了满足必填要求传入旧的图片URL,后端会尝试将该URL重新上传至Cloudinary。若该URL对应的资源已被销毁或不可访问,就会触发Cloudinary返回404资源未找到错误。
- 文本字段无判断覆盖:直接赋值
currentPost.title = title会导致空值覆盖原有内容,存在数据风险。
解决方案
1. 修改更新控制器逻辑
移除图片必填限制,仅在传入image参数时处理图片更新,同时增加文本字段的非空判断:
const updatePostController = async (req, res) => { try { const { title, description, image } = req.body; const currentPost = await Post.findById(req.params.id); if (!currentPost) { return res.status(404).json({ message: "Post not found" }); } // 仅传入image时才执行图片更新逻辑 if (image) { // 销毁旧图片(存在则执行) if (currentPost.image?.public_id) { await cloudinary.uploader.destroy(currentPost.image.public_id); } // 上传新图片 const uploadNewImg = await cloudinary.uploader.upload(image, { folder: "blog-mern-app" }); currentPost.image = {public_id:uploadNewImg.public_id, url:uploadNewImg.secure_url}; } // 仅传入有效内容时更新文本字段 if (title) currentPost.title = title; if (description) currentPost.description = description; await currentPost.save(); // 更新成功使用标准200状态码 res.status(200).json({ success:true, message:"updated post successfully", currentPost}); } catch (error) { console.error("error in blog post:", error); res.status(500).json({success:false, message: "error in updating blog post", error:error.message }); } }
2. 前端请求优化
仅更新文本字段时,请求体中不要包含image字段,避免触发后端的图片更新逻辑。
内容的提问来源于stack exchange,提问作者abhishek
相关产品推荐
相关产品推荐

