Multer文件上传读filename报undefined错误排查与修复
错误根因
- 核心错误是读取上传文件信息的路径写错:Multer 经过
upload.single()处理后,上传的单文件会挂载到req.file对象上,不会放到req.body里。你代码里写的req.body.file.filename本质是在不存在的对象上读属性,直接触发Cannot read property 'filename' of undefined报错。 - 配置存在冗余无效项:你把
fileSize字段写在了diskStorage的配置参数里,diskStorage本身不识别该配置,只有写在multer全局的limits字段里的大小限制才会生效,虽然这不是本次报错的直接原因,但属于无效配置需要清理。 - 缺少前置校验和错误捕获:当前逻辑没有判断文件是否上传成功、是否符合过滤规则就直接读取filename属性,只要出现文件没传、格式不符、大小超限的情况,
req.file就会是undefined,同样会触发该错误。另外你之前要的自定义错误提示没正常生效,也是因为没加Multer专属的错误捕获逻辑。 - Postman测试注意点:上传文件的表单字段名必须和
upload.single('image')里定义的字段名完全一致,也就是文件字段的key必须是image,写错字段名Multer不会解析文件,也会导致req.file为空。
修复步骤
1. 修正controller逻辑,增加文件存在校验
把原来读取filename的错误路径替换,加上空值判断,修改后的controller代码如下:
exports.create = (req, res, next) => { if (!req.body) { res.status(400).send({ message: "content cannot be empty !!" }) return } // 先判断文件是否存在 if (!req.file) { res.status(400).send({ message: "请上传符合要求的jpg/png图片,大小不超过5M" }) return } let data = { name: req.body.name, description: req.body.description, brand_url: req.body.brand_url, image_file: req.file.filename // 这里从req.file读取,不是req.body.file }; let sql = "INSERT INTO influencer SET ?"; db.query(sql, data, (err, results) => { if (err) throw err; console.log('data inserted succesfully') res.redirect('/admin'); }); }
2. 清理multer配置的无效字段
删掉diskStorage里多余的fileSize配置,修正后的multer.js代码如下:
const multer = require('multer'); const storage = multer.diskStorage({ // 删掉这里无效的fileSize配置 destination: function (req, file, cb) { cb(null, './uploads') }, filename: function (req, file, cb) { const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9) cb(null, file.fieldname + '-' + uniqueSuffix) } }) const filter = function (req, file, cb) { if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') { cb(null, true); } else { cb(new Error('unsupported files'), false) } } var upload = multer({ storage: storage, limits: { fileSize: 1024 * 1024 * 5 // 大小限制统一在这里配置 }, fileFilter : filter }); module.exports = upload;
3. 增加Multer错误捕获,正常返回自定义提示
在路由配置的最后加Multer专属的错误处理中间件,就能正常返回你之前配置的格式不支持、大小超限的错误提示,不会直接抛服务端异常:
// 在所有路由配置后面加错误处理中间件 app.use((err, req, res, next) => { if (err instanceof multer.MulterError) { // 处理Multer本身的错误,比如文件超限 return res.status(400).send({ message: `上传错误:${err.message}` }) } else if (err) { // 处理你自定义的fileFilter抛出的错误,比如格式不支持 return res.status(400).send({ message: err.message }) } next() })
4. Postman测试校验
测试时选择form-data格式传参,文件类型的字段key必须填image,和upload.single('image')的参数保持一致,不要写错成file或者其他名称。
内容的提问来源于stack exchange,提问作者Twice Lyrics
相关产品推荐
相关产品推荐

