如何在请求无文件时跳过Multer上传中间件并解决报错
解决Multer可选文件上传无附件时报错的问题
错误原因
报错TypeError Cannot read property 'originalname' of undefined是因为请求无文件时req.file为undefined,路由代码中直接访问req.file.originalname导致崩溃。要实现无文件时跳过上传中间件,可通过以下步骤处理:
1. 编写可选上传的包装中间件
创建一个中间件,仅当请求包含文件时才执行Multer上传逻辑,否则直接跳过:
const optionalUpload = (req, res, next) => { // 判断请求是否包含文件字段 const hasFile = req.headers['content-type']?.includes('multipart/form-data') && req.body?.file !== undefined; if (!hasFile) { return next(); } // 执行Multer上传逻辑,捕获错误并返回 upload(req, res, (err) => { if (err) { return res.status(400).json({ error: err.message }); } next(); }); };
2. 修改路由代码,兼容无文件场景
更新数据库时,判断req.file是否存在,动态设置attachment字段:
router.post('/user/book', optionalUpload, async (req, res) => { try { const ticketData = { eid: req.body.event_id, event_name: req.body.event_name, user_name: req.body.user_name, slot_duration: req.body.slot_duration, date: req.body.slot_date, sid: req.body.sid, start_time: req.body.slot_start_time, end_time: req.body.slot_end_time, description: req.body.description, available: false, status: 'booked', // 仅当存在文件时拼接地址,否则设为null attachment: req.file ? `${process.env.SPACE_DOMAIN}${req.file.originalname}` : null }; const user = await SlotUser.findOneAndUpdate( { _id: mongoose.Types.ObjectId(req.id) }, { $push: { tickets: ticketData } }, { new: true } // 可选:返回更新后的用户文档 ); if (!user) { return res.status(404).json({ error: '用户不存在' }); } res.json(user); } catch (err) { res.status(500).json({ error: err.message }); } });
补充说明
如果不需要完全跳过Multer中间件,也可以直接保留原upload中间件,仅修改路由中attachment的赋值逻辑即可。但使用包装中间件能避免无文件时执行不必要的Multer处理逻辑,性能更优。
内容的提问来源于stack exchange,提问作者Venkat Cpr
相关产品推荐
相关产品推荐

