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

如何修复Multer中间件无法创建上传文件夹及修改文件名的问题?

解决Multer文件上传未生效的问题

核心问题总结

你的代码存在4个关键错误,直接导致Multer无法正常工作:

  • 前端用JSON格式提交数据,而非FormData,文件二进制根本没传到后端
  • 前端文件DOM选择器ID写错(文件input的ID是pdf,代码里写了myfile)
  • 后端Multer配置里的日志引用了未定义变量
  • 上传目录未提前创建,Multer不会自动生成不存在的文件夹

分步修复代码

1. 修正前端EJS代码

必须用FormData包装表单数据(包括文件),不能用JSON提交:

<form enctype="multipart/form-data">
  <input type="text" placeholder="Book Name" id="name" />
  <input type="text" placeholder="Author " id="author" />
  <input type="text" placeholder="Buy link" id="link" />
  <input type="text" placeholder="Book description" id="desc" />
  <input type="file" name="pdf" id="pdf" placeholder="upload file" />
  <button type="submit">Add</button>
</form>
<script>
let form = document.querySelector("form");
form.addEventListener("submit", async (e) => {
  e.preventDefault();
  // 用FormData自动收集所有表单数据(含文件)
  const formData = new FormData(form);
  
  try {
    const res = await fetch("/addBooks", {
      method: "POST",
      body: formData // 直接传FormData,浏览器会自动设置正确的请求头
    });
    const result = await res.json();
    console.log(result);
  } catch (err) {
    console.error(err);
  }
});
</script>

修正说明:

  • 替换JSON提交为FormData,确保文件二进制数据能被后端接收
  • 移除手动设置的Content-Type,浏览器会为FormData自动配置multipart/form-data头
  • 修复文件选择器ID错误(从myfile改为pdf)

2. 修正后端Multer中间件代码

const multer = require('multer');
const fs = require('fs');
const path = require('path');

// 提前创建upload目录,不存在则自动生成
const uploadDir = path.join(__dirname, 'upload');
if (!fs.existsSync(uploadDir)) {
  fs.mkdirSync(uploadDir, { recursive: true });
}

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'upload');
  },
  filename: function (req, file, cb) {
    const newFilename = `${Date.now()}-${file.originalname}`;
    cb(null, newFilename);
    // 修正日志变量,输出实际保存路径和文件名
    console.log('保存路径:', 'upload', '文件名:', newFilename);
  },
});
const upload = multer({ storage });

route.post("/addBooks", upload.single("pdf"), addBook);

修正说明:

  • 添加目录检测与创建逻辑,确保upload文件夹存在
  • 修复日志中未定义变量的错误,改用实际生成的文件名
  • 补充multer的引入语句(原代码遗漏)

3. 修正处理函数代码

文件上传后,文件信息存在req.file中,文本字段在req.body中,需从req.file.filename获取重命名后的文件名:

let addBook = async (req, res) => {
  console.log("文本字段 >> ", req.body);
  console.log("文件信息 >> ", req.file);
  
  // 校验是否有文件上传
  if (!req.file) {
    return res.status(400).send({ msg: "请上传PDF文件" });
  }

  let { bookName, bookAuthor, bookDesc, bookLink } = req.body;
  // 从Multer处理后的文件对象中获取最终文件名
  let pdfFilename = req.file.filename;

  try {
    let _book = await books.create({
      name: bookName,
      author: bookAuthor,
      description: bookDesc,
      buyLink: bookLink,
      pdf: pdfFilename
    });
    res.status(200).send({ msg: "success" });
  } catch (error) {
    console.error("系统错误:", error);
    res.status(400).send({ msg: "Wrong" });
  }
};

修正说明:

  • 从req.file.filename获取重命名后的文件名,而非前端传的原文件名
  • 添加文件上传校验,避免空文件提交
  • 完善错误日志,输出具体错误信息便于排查

验证步骤

  1. 启动后端服务,确认upload目录已自动生成
  2. 前端选择PDF文件并提交表单
  3. 检查upload目录下是否出现带时间戳的PDF文件
  4. 验证数据库是否正确保存了重命名后的文件名

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:05:02