解析多部分表单数据,然后使用Multer(节点模块)上传文件

时间:2016-05-31 13:30:13

标签: node.js express multipartform-data multer

如果条目已经添加到数据库中,我有一些麻烦试图弄清楚如何阻止Multer上传文件。

在我的场景中,我有一个多部分表单,您可以在其中添加指定ID的啤酒。它有2个输入,一个带文本输入(id),另一个带文件输入(beerImage)。

我想要做的是,在上传文件之前,检查数据库中是否已存在,如果没有,则上传文件。目前,我的代码首先上传文件,然后检查文件是否存在,这是件坏事!

那是我的代码:

var express = require('express');
var router = express.Router();
var multer = require('multer');
var database = require('../services/database');

var upload = multer({ dest: 'uploads/' });
var cpUpload = upload.fields([{ name: 'beerImage', maxCount: 1 } ]);

router.route('/beers')
    .post(function (req, res, next) {
        // I'd like to use req.body.id in the query here, but it doesn't exist yet!
        cpUpload(req, res, function (err) {
            if (err) {
                return next(new Error('Error uploading file: ' + err.message + ' (' + err.field + ')'));
            } else {
                database.getConnection().done(function (conn) {
                    conn.query('SELECT COUNT(*) AS beersCount FROM beers WHERE id=?', req.body.id, function (err, rows, fields) {
                        if (err) {
                            conn.release();
                            return next(err);
                        }

                        if (rows[0].beersCount > 0) {
                            conn.release();
                            return next(new Error('Beer "' + req.body.id + '" already exists!'));
                        } else {
                            delete req.body.beerImage;
                            conn.query('INSERT INTO beers SET ?', req.body, function (err, rows, fields) {
                                conn.release();

                                if (err) {
                                    return next(err);
                                }

                                res.json({ message: 'Beer "' + req.body.id + '" added!' });
                            });
                        }
                    });
                });
            }
        });
    });

module.exports = router;

我找不到第一个解析"的方法。多部分表单数据(能够执行查询并使用req.body.id检查它是否存在),然后决定是否要上传文件。好像" cpUpload"同时做两件事!

如何获得" req.body.id"首先(进行查询),然后决定是否要上传文件?

3 个答案:

答案 0 :(得分:0)

如果文件存在,您必须在测试前上传文件。然后保存或删除它

答案 1 :(得分:0)

我意识到有一个名为" fileFilter"在Multer,您可以控制哪些文件被接受。在这里,我已经能够执行所需的查询以检查条目是否存在。

答案 2 :(得分:0)

  • 这就是我在上传到云之前实现 multipart/formdata 的文件字段和文本字段验证的方法。我在 filterFile 中的 multer 函数如下所示:
  • 请注意,使用 postman 的 formdata 发送的任何数据都被视为 multipart/formdata。您必须使用 multer 或其他类似的库来解析表单数据。
  • 对于 x-www-form-urlencodedraw 来自 postman 的数据不需要 multer 进行解析。您可以使用 body-parser 或表达内置中间件 express.json()express.urlencoded({ extended: false, })
  • 解析这些数据
        filterFile = async (req, file, cb) => {
        // if mimetypes are expected mimetypes

        const allowedMimeTypes = ["image/jpeg", "image/jpg", "image/png"];
        if (allowedMimeTypes.includes(file.mimetype)) {
          // then validate formdata fields
          // reject the request with error if any validation fails

          try {
            let { highlights, specifications, ...rest } = req.body;

            // deserializing string into respective javascript object(here into an array datatype) to facilate validation
            highlights = JSON.parse(req.body.highlights);
            specifications = JSON.parse(req.body.specifications);
            
            // constructing deserialized formdata
            const formdata = { highlights, specifications, ...rest };

            // using Joi for validation
            let skuAndProductResult = await skuAndProductSchema.validateAsync(
              formdata
            );

            if (skuAndProductResult) {
              // accept the fields and proceed to the next middleware
              cb(null, true);
              return;
            }

            // reject the request with error
            cb(true, false);
            return;
          } catch (err) {
            // reject the request with error
            cb(err, false);
          }
        } else {
          // To reject this file pass `false`
          cb(`${file.mimetype} is not supported`, false);
        }
      };