首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >快速验证器两次返回验证错误。

快速验证器两次返回验证错误。
EN

Stack Overflow用户
提问于 2019-09-23 19:47:25
回答 2查看 3.7K关注 0票数 7

我想使用Express-Validator验证请求对象。假设我有两条路由,GET /users/:id (fetchUserById)和POST /users (createUser)路由

代码语言:javascript
运行
复制
this.router = express.Router();
this.router.route('/').post(this.userRequestValidator.createUser, this.userController.createUser);
this.router.route('/:id').get(this.userRequestValidator.fetchUserById, this.userController.fetchUserById);

如您所见,在调用控制器逻辑之前,我直接调用验证中间件。首先,我创建了一个处理验证错误的基本验证器,并在发生故障时返回HTTP 400。

代码语言:javascript
运行
复制
export abstract class RequestValidator {
    protected validate = async (request: Request, response: Response, next: NextFunction): Promise<void> => {
        const errors: Result<ValidationError> = validationResult(request);

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

我的验证器函数userRequestValidator.createUser和userRequestValidator.fetchUserById只需扩展RequestValidator并实现验证

代码语言:javascript
运行
复制
export class UserRequestValidator extends RequestValidator {
    public createUser = [
        body('username')
            .isString()
            .exists(),
        body('password')
            .isString()
            .exists(),
        this.validate,
    ];

    public fetchUserById = [
        param('id')
            .isString()
            .isUUID()
            .exists(),
        this.validate,
    ];
}

当我打电话给GET localhost:3000/users/abc时,我会得到这样的响应

代码语言:javascript
运行
复制
{
    "errors": [
        {
            "value": "abc",
            "msg": "Invalid value",
            "param": "id",
            "location": "params"
        }
    ]
}

这是我期待的回应。但是当我用一个空的身体调用POST localhost:3000/users时,我会得到这样的响应

代码语言:javascript
运行
复制
{
    "errors": [
        {
            "msg": "Invalid value",
            "param": "username",
            "location": "body"
        },
        {
            "msg": "Invalid value",
            "param": "username",
            "location": "body"
        },
        {
            "msg": "Invalid value",
            "param": "password",
            "location": "body"
        },
        {
            "msg": "Invalid value",
            "param": "password",
            "location": "body"
        }
    ]
}

有人知道我怎样才能纠正这种行为吗?或者我的设置有什么问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-26 07:12:30

我不知道为什么当req.body是一个空对象- {}时,验证器将运行于验证链的所有节点。您可以再次检查,为每个条件添加每个消息,如下所示:

代码语言:javascript
运行
复制
class UserRequestValidator extends RequestValidator {
  public createUser = [
    body('username')
      .isString().withMessage('username must be a string') // you can see both error messages in the response
      .exists().withMessage('username must be exist'),
    body('password') // the same for this field
      .isString()
      .exists(),
    this.validate,
  ];

  public fetchUserById = [
    param('id') // because id is exist in `req.params`, then only one test has been executed.
      .isString().withMessage('id must be a string')
      .isUUID()
      .exists(),
    this.validate,
  ];
}

我在https://github.com/express-validator/express-validator/issues/638中为您的情况找到了一个解决方案,使用.bail()函数在第一个错误中停止链。

然后,您的验证器类将类似于:

代码语言:javascript
运行
复制
class UserRequestValidator extends RequestValidator {
  public createUser = [
    body('username')
       // always check exists() first
      .exists().withMessage('username must be exist').bail()
      .isString().withMessage('username must be a string').bail(),
    body('password')
      .exists().bail()
      .isString().bail(),
    this.validate,
  ];

  public fetchUserById = [
    param('id')
      .isString()
      .isUUID()
      .exists(),
    this.validate,
  ];
}
票数 12
EN

Stack Overflow用户

发布于 2021-05-09 15:30:21

在检索错误数组时,还可以将onlyFirstError设置为true。来自文档

如果选项onlyFirstError设置为true,则只包含每个字段的第一个错误。

示例用法:

代码语言:javascript
运行
复制
function validateRequestParams (req, res, next) {
    const errors = validationResult(req)

    if (errors.isEmpty()) {
        return next()
    } else {
        return res.status(400).json({
            bodyValidationErrors: errors.array({ onlyFirstError: true })
        })
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58069250

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档