Node.js中间件中如何获取Promise包裹的文件MIME类型?
如何在Node.js中间件中正确访问上传文件Promise对象里的mimetype属性
核心问题很明确:你看到的variables.file是一个Promise对象,它包裹着实际的文件信息,所以不能直接通过点语法或者键访问来获取mimetype,必须先等待这个Promise完成(resolve)才行。
修复步骤
- 等待Promise resolve:在你的异步
res.end函数里,对variables.file使用await,拿到实际的文件对象。 - 添加类型校验逻辑:拿到文件对象后,就可以正常访问
mimetype,然后和你定义的acceptedImageTypes对比,不符合就返回错误。 - 确保中间件逻辑顺序正确:处理完校验后再调用原始的
oldEnd方法,保证响应正常发送。
修改后的完整中间件代码
export const fileCheckMiddleware = (req, res, next) => { const acceptedImageTypes = ["image/gif", "image/jpeg", "image/png"]; const oldWrite = res.write; const oldEnd = res.end; const chunks = []; res.write = (...restArgs) => { chunks.push(Buffer.from(restArgs[0])); // 推荐用Buffer.from代替已废弃的new Buffer oldWrite.apply(res, restArgs); }; res.end = async (...restArgs) => { if (restArgs[0]) { chunks.push(Buffer.from(restArgs[0])); } try { const body = Buffer.concat(chunks).toString("utf8"); let parsedBody = {}; try { parsedBody = JSON.parse(body); } catch (err) { parsedBody = { data: { unparsedBody: body } }; } const { variables } = req.body; if (variables?.file) { // 等待Promise resolve,拿到实际的文件对象 const file = await variables.file; console.log("\x1b[1m%s\x1b[0m", "LOG file info", file); // 校验文件类型,不通过则直接返回错误 if (!acceptedImageTypes.includes(file.mimetype)) { return res.status(400).json({ error: "Invalid file type", allowedTypes: acceptedImageTypes }); } } } catch (err) { console.error("File check middleware error:", err); return res.status(500).json({ error: "Internal server error" }); } oldEnd.apply(res, restArgs); }; next(); };
关键说明
- 为什么之前的方法无效?Promise对象本身没有
mimetype属性,你看到的{ filename: 'trump.jpeg', ... }是Promise resolve后的值,必须通过await或.then()才能获取。 - 增加了可选链
variables?.file:避免variables不存在时抛出不必要的错误。 - 校验不通过时直接返回错误响应,不再继续执行后续逻辑,符合中间件的拦截特性。
内容的提问来源于stack exchange,提问作者Gh05d




