Node Express - 在 multer 保存文件之前处理表单数据

问题描述 投票:0回答:1

我想做以下事情:

  1. 用户使用 FORM 创建请求
  2. 表单包含输入字段和多部分文件
  3. 首先我想使用
    express validator
  4. 验证输入字段
  5. 之后,如果输入有效,我想使用
    multer
  6. 保存多部分文件

我的问题:如果我尝试在 multer 解析输入字段之前访问它们,那么输入字段将是未定义的。如果我尝试在 multer 解析输入字段后访问它们,那么输入字段是可以访问的,但在我验证输入字段之前文件已经保存了

目前我的中间件按以下顺序执行:

app.post('/upload', upload.array('files', 50), uploadFormValidation, uploadController.postUpload);

我想按以下顺序执行中间件:

app.post('/upload', uploadFormValidation, upload.array('files', 50), uploadController.postUpload);

我怎样才能实现这个目标?

node.js express multer
1个回答
0
投票

好吧,我知道的不多,但我做到了。先验证后保存。 问题是我们通过 URL 发送验证所需的内容,这样我们就可以从“req.params”收集它们进行验证,然后调用 Multer 来保存文件。 注意:我不知道我们是否应该这样做,但就我而言,我没有 Multer 作为中间件。所以,我的请求都没有经过 Multer。一旦控制器进行验证,我就调用这个 Multer 函数。

const uploadBusinessLogo = async (req, res) => {
if (req.is("multipart/form-data")) {
    console.log("The request is of type multipart/form-data");
  } else if (req.is("application/json")) {
    console.log("The request is of type application/json");
  } else {
    console.log("The request has a different content type");
  }

  const { currentBusinessID } = req.params;

  if (!currentBusinessID)
    return res.status(400).json({
      message: `BusinessID missing in request. Cannot upload business logo without a reference to business.`,
    });

  const connection = await pool.getConnection();

  const isUserAssociateWithBusiness = await isUserAssociatedWithTheBusiness(
    req.user,
    currentBusinessID,
    connection
  );
  if (!isUserAssociateWithBusiness)
    return res.status(403).json({
      message: `Access Denied. You are not associated with this business.`,
    });  

try {
    await connection.beginTransaction();
    const businessDetail = await fetchBusinessDetailByID(
      currentBusinessID,
      connection
    );
    if (!businessDetail)
      return res
        .status(400)
        .json({ message: `Couldn't find the business to upload its logo.` });

    const businessLogoUploadResult = await uploadBusinessLogos(businessDetail)(
      req,
      res
    );
    console.log("WHAT", businessLogoUploadResult);

    if (!businessLogoUploadResult)
      return res
        .status(500)
        .json({ message: `Error while uploading business logo.` });

    const filePath = businessLogoUploadResult.path;
    const updateBusinessLogoPathResult = await updateBusinessLogoPath(
      currentBusinessID,
      filePath,
      connection
    );

    if (!updateBusinessLogoPathResult)
      return res.status(500).json({
        message: `Failed to link the uploaded logo with the business. Reverting the upload.`,
      });

    await connection.commit();
    return res.status(201).json("Business logo uploaded successfully.");
  } catch (error) {
    console.log(error);
    await connection.rollback();
  } finally {
    connection.release();
  }
};

而 multer 的事情是这样的:

const storageForBusinessLogo = (businessDetail) => {
  return multer.diskStorage({
    destination: (req, file, cb) => {
      cb(null, path.join(__dirname, "..", "uploads", "businessLogos"));
    },
    filename: (req, file, cb) => {
      const timeStamp = Date.now();
      const fileExtension = path.extname(file.originalname).toLowerCase();
      const fileName = `${businessDetail.registrationType}${businessDetail.registeredID}_${timeStamp}${fileExtension}`;
      cb(null, fileName);
    },
  });
};


const uploadBusinessLogos = (businessDetail) => {
  const upload = multer({
    storage: storageForBusinessLogo(businessDetail),
    limits: { fileSize: 2 * 1024 * 1024 },
    fileFilter: (req, file, cb) => {
      const allowedTypes = /jpeg|jpg|png|pdf/;
      const isValidType = allowedTypes.test(
        path.extname(file.originalname).toLowerCase()
      );

      if (isValidType) cb(null, true);
      else {
        console.log(error);
        cb(new Error("Only jpeg, jpg, png and pdf files are allowed."));
      }
    },
  }).single("businessLogo");

  return (req, res) => {
    return new Promise((resolve, reject) => {
      upload(req, res, (error) => {
        if (error) return reject(error);
        console.log("PROFILE", req.file);
        resolve(req.file);
      });
    });
  };
};
© www.soinside.com 2019 - 2024. All rights reserved.