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

Postman测试multer图片上传报ENOENT 文件名初始为undefined

报错修复:Error: ENOENT: no such file or directory(上传文件名为undefined)

你的代码存在3个直接触发报错的问题,逐个修复即可:

  • multer文件名配置字段错误
    你在multer的filename回调中使用了file.filename属性,该属性是multer完成文件存储后才会挂载到req.file对象上的,回调入参的原始文件信息对象中不存在这个字段,仅包含originalname(用户上传的原始文件名)等属性,因此拼接出的文件名前缀固定为undefined,也就是你观测到的文件名异常问题。
  • 文件路径不匹配+存储目录未提前创建
    1. multer配置的上传存储目录为./src/image/,但控制器中读取文件的路径是__dirname + "/images/",二者目录名(单复数不同)、层级完全不匹配,读取时必然找不到目标文件。
    2. multer不会自动创建不存在的存储目录,如果未手动提前创建配置中指定的目标文件夹,文件写入阶段就会直接抛出路径不存在错误。
    3. 禁止用相对路径编写文件目录,node运行时工作目录变动会导致相对路径偏移,所有路径统一用path.resolve()转为绝对路径。
  • 控制器逻辑冗余冲突
    multer本身已经会将上传文件存储到你配置的目标目录,你代码中额外编写的读文件、二次写文件逻辑完全冗余。且Comment.create()返回的是数据库插入的记录对象,不存在你代码中写的image.name、image.data属性,二次写入文件时必然触发路径错误。另外你创建Comment记录时未传入image字段,后续也无法关联查询到对应上传文件。

修复代码

1. 路由层multer配置修复

首先手动在项目对应位置创建好存储图片的文件夹,再替换路由配置:

const express = require("express");
const router = express.Router();
const commentCtrl = require("../controllers/comment");
const { authJwt } = require("../middleware");
const path = require('path')
const multer = require("multer");

// 统一用绝对路径定义上传目录,避免路径偏移,根据你的实际目录调整层级
const UPLOAD_PATH = path.resolve(__dirname, '../image/');
const storage = multer.diskStorage({
  destination: UPLOAD_PATH,
  filename: (req, file, cb) => {
    // 生成唯一文件名,用原始文件的后缀名,禁止使用不存在的file.filename
    const uniqueSuffix = `${Date.now()}-${Math.round(Math.random() * 1E9)}`
    cb(null, `${uniqueSuffix}${path.extname(file.originalname)}`);
  },
});

const uploadFile = multer({ storage: storage });
// 注意uploadFile.single的参数必须和Postman里上传的文件字段名完全一致
router.post("/upload", [authJwt.verifyToken], uploadFile.single('image'), commentCtrl.createComment);
router.get("/",[authJwt.verifyToken], commentCtrl.getallComment);

module.exports = router;

2. 控制器层逻辑修复

删除冗余的文件读写操作,直接将multer生成的文件路径存入数据库即可:

const { Comment } = require("../models");
const path = require('path');
// 和路由层的上传根路径保持一致
const UPLOAD_PATH = path.resolve(__dirname, '../image/');

module.exports.createComment = async (req, res) => {
  try {
    if (!req.body.message) {
      return res.status(400).send({ message: "Content can not be empty!" });
    }
    if (!req.file) {
      return res.status(400).send({ message: "You must select a file." });
    }
    const { id, message, date } = req.body;
    // 存入数据库的是可访问的文件相对路径,不需要存储文件二进制内容
    const imageUrl = `/image/${req.file.filename}`;

    const comment = await Comment.create({
      id,
      message,
      date,
      image: imageUrl
    });
    
    return res.status(201).send(comment);
  } catch (error) {
    console.log(error);
    return res.status(500).send(`Error when trying upload images: ${error.message}`);
  }
};

额外配置检查

  • Postman上传时必须选择form-data格式,文件字段的key为image(和uploadFile.single()的参数完全一致),字段类型选择File后再选中本地图片,不要选Text类型。
  • 如果需要前端直接访问上传的图片,在express入口文件中添加静态资源映射:
    app.use('/image', express.static(path.resolve(__dirname, 'image/')))
    
    配置后可直接通过http://服务域名/image/文件名访问对应图片。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:06:12