You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Node.js中间件中如何获取Promise包裹的文件MIME类型?

如何在Node.js中间件中正确访问上传文件Promise对象里的mimetype属性

核心问题很明确:你看到的variables.file是一个Promise对象,它包裹着实际的文件信息,所以不能直接通过点语法或者键访问来获取mimetype,必须先等待这个Promise完成(resolve)才行。

修复步骤

  1. 等待Promise resolve:在你的异步res.end函数里,对variables.file使用await,拿到实际的文件对象。
  2. 添加类型校验逻辑:拿到文件对象后,就可以正常访问mimetype,然后和你定义的acceptedImageTypes对比,不符合就返回错误。
  3. 确保中间件逻辑顺序正确:处理完校验后再调用原始的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

火山引擎 最新活动