为什么快速验证器oneOf无法正常工作

时间:2019-12-17 20:44:28

标签: node.js express express-validator

我正在NodeJS中构建一个项目,我也在使用Express。为了验证来自客户端的请求,我使用Express验证程序,并使用check,oneOf,body等方法。 我建立了我的PUT端点,并同时使用oneOf对字段进行了验证以进行更新。我的目标是,当客户端尝试更新时,至少应更改其中一个字段,否则将出现一条消息,通知客户端未进行任何更新。 我的问题是PUT更新时忽略了我实施的检查,因此无法理解该问题,因为我之前已经做过类似的事情并且运行良好。

我的更新验证程序如下:

const updateBookRules = [
    oneOf([
        check("title")
            .exists()
            .withMessage("Title is required"),
        check("category")
            .exists()
            .withMessage("Category is required"),
        check("price")
            .isNumeric()
            .withMessage("Price should be a number"),
        check("img")
            .exists()
            .withMessage("Img is required"),
        sanitizeBody("price").toFloat()
    ])
];

在路线中,我将此验证称为:

// PUT Update a book
router.put("/:asin", check.updateBook, check.rules, async (req, res) => {
    // Request ID
    const asin = req.params.asin;
    // Await the book
    await book
        // Call model to update the product
        .updateBook(asin, req.body)
        // Response a message
        .then(book =>
            res.json({
                message: `The book #${asin} has been updated`,
                content: book
            })
        )
        // Errors if any
        .catch(err => {
            if (err.status) {
                res.status(err.status).json({ message: err.message });
            }
            res.status(500).json({ message: err.message });
        });
});

奇怪的是验证被忽略了,我也可以放入空字符串,并且没有错误发生,我不知道我的错误是什么。

如果您想了解更多内容,请发表评论,我将更新问题。

1 个答案:

答案 0 :(得分:0)

编辑答案

我想我可能知道这个问题。现在我已经可以访问整个存储库,您的代码看起来不错,但是您绝对需要引入validationResult来检查验证错误,然后停止执行路由器中间件。因此,router.put路由处理程序将以:

const { validationResult } = require('express-validator');

// PUT Update a book
router.put("/:asin", check.updateBook, check.rules, async (req, res) => {

    // Finds the validation errors in this request and wraps them in an object with handy functions
    const errors = validationResult(req);

    if (!errors.isEmpty()) {
        return res.status(422).json({ errors: errors.array() });
    }

我仍然不确定如何设置updateBookRules以使用sanitizeBody()调用,以及如何将其包装在数组中。如果在添加validationResult之后上述操作仍然无效,请尝试以下操作:

const updateBookRules = oneOf([
        check("title")
            .exists()
            .withMessage("Title is required"),
        check("category")
            .exists()
            .withMessage("Category is required"),
        check("price")
            .isNumeric()
            .withMessage("Price should be a number"),
        check("img")
            .exists()
            .withMessage("Img is required"),    
]);

然后进行路由处理程序签名:

router.put("/:asin", sanitizeBody("price").toFloat(), check.updateBook, check.rules, async (req, res) => {

另外,您确定有错误吗? docs指出oneOf:

  

创建一个中间件实例,该实例将确保至少一个   给定的链条通过了验证。

您正在检查以确保在PUT路由上存在这些不同的字段。只要其中一个存在,check.updateBook就会通过。您不是在这里检查更改,因此用户可以简单地向您发送相同的图书信息,而不会出现任何错误?

根据您的评论,如果您真的不想使用validationResult,则可以尝试强制执行验证,请查看docs