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

Node.js中Multer+MongoDB博客图片上传的问题排查

博客系统图片上传异常排查与修复

问题根源分析

  • 表单嵌套:HTML不允许表单嵌套,外层<form>与内层<form>冲突,导致第一次提交无法正确触发逻辑,第二次提交时浏览器忽略内层表单才完成有效提交。
  • Multer中间件未挂载:POST路由未添加Multer的文件解析中间件,req.file未被正确初始化,后续逻辑出错。
  • 错误调用req.file.mv:mv是express-fileupload库的方法,而非Multer的API,Multer通过diskStorage已完成文件存储,手动调用该方法触发类型错误,同时重复生成文件名导致数据库路径与实际文件路径不一致。

分步修复

1. 修复表单嵌套问题

删除_form_fields.ejs中的外层<form>标签,仅保留表单字段(外层new.ejs已包含完整表单):

<div class="form-group">
  <label for="title">Title</label>
  <input required value="<%= article.title %>" type="text" name="title" id="title" class="form-control">
</div>

<div class="form-group">
  <label for="description">Description</label>
  <textarea name="description" id="description" class="form-control"><%= article.description %></textarea>
</div>

<div class="form-group">
  <label for="markdown">Markdown</label>
  <textarea required name="markdown" id="markdown" class="form-control"><%= article.markdown %></textarea>
</div>

<div class="form-group">
  <label for="image">Image</label>
  <input type="file" name="image" id="image" class="form-control">
</div>

<a href="/" class="btn btn-secondary">Cancel</a>
<button type="submit" value="upload" class="btn btn-primary">Save</button>

2. 挂载Multer中间件到POST路由

在POST路由中添加upload.single('image'),确保Multer解析上传文件:

router.post('/', upload.single('image'), async (req, res, next) => {
  if (!req.file) {
    console.log('No file received!');
  } else {
    console.log(req.file);
  }
  req.article = new Article();
  next();
}, saveArticleAndRedirect('new'));

3. 修正文件存储逻辑,删除错误的req.file.mv调用

Multer的diskStorage已自动完成文件存储和唯一文件名生成,直接使用req.file提供的路径信息填充数据库字段:

const saveArticleAndRedirect = (path) => {
  return async (req, res, next) => {
    let article = req.article;
    article.title = req.body.title;
    article.description = req.body.description;
    article.markdown = req.body.markdown;

    try {
      if (req.file) {
        // 存储完整路径,或根据前端需求改为相对路径(如`/uploads/${req.file.filename}`)
        article.image = req.file.path;
      }

      article = await article.save();
      res.redirect(`/articles/${article.slug}`);
    } catch (e) {
      console.error(e);
      res.render(`articles/${path}`, { article: article, error: e.message });
    }
  };
};

验证效果

修复后,单次点击保存按钮即可完成提交,图片文件由Multer自动存储到指定目录,MongoDB的Article文档image字段会被正确填充为文件路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:53:12