Postman测试multer图片上传报ENOENT 文件名初始为undefined
报错修复:
Error: ENOENT: no such file or directory(上传文件名为undefined) 你的代码存在3个直接触发报错的问题,逐个修复即可:
- multer文件名配置字段错误
你在multer的filename回调中使用了file.filename属性,该属性是multer完成文件存储后才会挂载到req.file对象上的,回调入参的原始文件信息对象中不存在这个字段,仅包含originalname(用户上传的原始文件名)等属性,因此拼接出的文件名前缀固定为undefined,也就是你观测到的文件名异常问题。 - 文件路径不匹配+存储目录未提前创建
- multer配置的上传存储目录为
./src/image/,但控制器中读取文件的路径是__dirname + "/images/",二者目录名(单复数不同)、层级完全不匹配,读取时必然找不到目标文件。 - multer不会自动创建不存在的存储目录,如果未手动提前创建配置中指定的目标文件夹,文件写入阶段就会直接抛出路径不存在错误。
- 禁止用相对路径编写文件目录,node运行时工作目录变动会导致相对路径偏移,所有路径统一用
path.resolve()转为绝对路径。
- multer配置的上传存储目录为
- 控制器逻辑冗余冲突
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
相关产品推荐
相关产品推荐

