博客应用实现无图片发布功能时遭遇url未定义错误求助
实现博客文章图片非必填的解决方案
1. 修改 createPost 控制器逻辑
创建文章时,仅当用户上传了图片(file 存在)时才调用Cloudinary上传接口,否则跳过上传步骤:
const createPost = async (req, res) => { const { title, file, tags, body, authorUsername } = req.body; // 初始化image对象,无图片时为空对象 let image = {}; if (file) { // 仅当有图片时才执行上传 const { url, public_id: publicId } = await uploadToCloudinary(file, 'Posts'); image = { url, publicId }; } const author = await User.findOne({ username: authorUsername }).exec(); const formattedTags = tags .trim() .split(',') .map(w => w.trim().replace(/ /g, '-')); const createdPost = await Post.create({ title, image, // 无图片时传入空对象,mongoose会自动处理 body, author: author._id, }); // 以下原有逻辑保持不变 author.followers.map(followerId => { (async () => { await postNotification(author._id, createdPost._id, followerId); })(); }); await createTags(formattedTags, createdPost); author.posts.push(createdPost._id); await author.save(); res.status(200).json(createdPost.toObject({ getters: true })); };
2. 修改 updatePost 控制器逻辑
更新文章时,仅当用户提供了新的图片URL时,才执行上传和旧图片删除操作:
const updatePost = async (req, res) => { const authorId = await User.findOne({ username: req.params.username }).exec(); const { postTitle, postId } = getPostParams(req.params.postUrl); // 仅当存在新图片URL时,才执行上传和替换逻辑 if (req.body.image?.url) { const { url, public_id: publicId } = await uploadToCloudinary(req.body.image.url, 'Posts'); // 删除旧图片 await cloudinary.uploader.destroy(req.body.image.publicId); req.body.image = { url, publicId }; } else { // 无新图片时,删除req.body.image,避免覆盖原有图片数据 delete req.body.image; } const formattedTags = req.body.tags .trim() .split(',') .map(w => w.trim().replace(/ /g, '-')); const post = await Post.findOne({ author: authorId, title: postTitle, _id: postId, }) .populate('author') .populate('tags'); Object.keys(req.body).map(key => { if (key !== 'tags') post[key] = req.body[key]; }); await updateTags(formattedTags, post); await post.save(); res.status(200).json(post.toObject({ getters: true })); };
3. 修复删除操作中的图片处理逻辑
避免无图片时调用Cloudinary销毁接口报错:
修改 deletePostsByUserId 函数
posts.forEach(post => { (async () => { await deleteTags( post.tags.map(({ name }) => name), post, true ); // 仅当存在图片publicId时才销毁 if (post.image?.publicId) { await cloudinary.uploader.destroy(post.image.publicId); } await Post.deleteOne({ _id: post._id }); })(); });
修改 deletePost 函数
// 仅当传入了publicId时才销毁图片 if (req.body.publicId) { await cloudinary.uploader.destroy(req.body.publicId); }
4. 确认Post模型配置(无需修改)
你的Post模型已经正确设置了image字段为非必填,无需额外修改:
image: { url: { type: String }, publicId: { type: String } },
内容的提问来源于stack exchange,提问作者samurai
相关产品推荐
相关产品推荐

