NodeJS Multer 在上传前验证字段

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

我在上传图片之前尝试验证我的表单,但我的中间件上出现空字符串

const upload = multer({
  storage: storage
});

router.post('/upload', formsValidation, upload.fields([{

  name: 'images',
  maxCount: 20

}, {

  name: 'imageMain',
  maxCount: 1

}]), function(req, res, next) {
  code...

});

这是我的中间件:

function formsValidation (req, res, next) {

  console.log(req.body) //getting empty array here
  return next();
}

我知道我可以使用 multer 的 fileFilter 但有时我没有任何图像可以上传只是字符串来存储和验证,我试图将 req.body 从 multipart/form-data 解析为字符串然后验证并使用 next( ) 但我得到一个范围错误,我该如何解决这个问题?

javascript node.js validation express multer
2个回答
1
投票

这是来自 Multer 的docs

请注意,req.body 可能尚未完全填充。这取决于 按照客户端将字段和文件传输到服务器的顺序。

这意味着你必须在 multer 中间件之后调用

formsValidation
,以确保所有发布的数据都已完全填充

router.post('/upload', upload.fields([{

    name: 'images',
    maxCount: 20

}, {

    name: 'imageMain',
    maxCount: 1

}]), formsValidation, function(req, res, next) {
    code...
});

0
投票

问题

在调用Multer中间件之前(

upload.fields(...)
),请求体还没有开始解析。您在
req
中间件中收到的 Express
formValidation()
对象只是
http.IncomingMessage
的实例,它本身是
stream.Readable
的实例,其数据尚未被消费。只有在您调用 Multer
upload.fields(...)
中间件(或 Multer 提供的任何其他中间件)后,
req
流才会通过
Busboy
(Multer 使用的
multipart/form-data
请求解析器)进行管道传输,然后解析字段和文件并填充(按它们出现的顺序)
req.body
.

解决方案

不幸的是,Multer 不提供处理现场事件的功能,只提供文件。您可以在收到文件之前验证

req.body
中填充的字段(如 this Github issue 中所述),但是:

  1. 将您的验证实现与 Multer 的 API 紧密联系在一起;
  2. 正如您自己所说,在某些情况下您可能没有发送/接收任何文件,但仍想验证字段。

我不知道有任何其他使用 Multer 的解决方法。这就是为什么我写了

pechkin
来解决这个确切的问题。

  • pechkin.parseFormData()
    返回一个
    Promise
    ,它在所有字段都被解析时解析,and 如果遇到第一个文件(或请求结束)。
  • 承诺包含一个填充的
    fields
    对象,和一个
    files
    AsyncIterator/AsyncIterable
    .
  • 无需提供存储引擎、文件处理器、事件监听器等

这意味着您可以对

fields
对象执行验证,然后才需要处理文件——文件不会被解析、处理、写入内存、保存在任何地方等,直到您决定这样做。

// ESM
import { parseFormData } from 'pechkin';

// CommonJS
const { parseFormData } = require('pechkin');

// ...

app.post(
  '/upload',
  pechkinFileUpload(/* ...optional configs */),
  formsValidation,
  (req, res, next) => {
    // Process files and/or fields (`req.files`) ...
  }
);

function formsValidation (req, res, next) {
  console.log(req.body) // No longer empty! Populated with all fields (see note)
  return next();
}

// Just a utility function to follow Express' middleware style
function pechkinFileUpload (/* ...optional configs */) {
  return async (req, res, next) => {
    try {
      const { fields, files } = await parseFormData(req, /* ...optional configs */);

      req.body = fields;
      req.files = files;

      return next();
    } catch (err) {
      return next(err);
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.