joi_1.default.validate 不是函数

joi_1.default.validate is not a function

我想在调用控制器逻辑之前验证我的 Express 路由。我使用 joi 并创建了一个验证器,它能够根据模式对象验证请求对象

import { Request, Response, NextFunction } from 'express';
import joi, { SchemaLike, ValidationError, ValidationResult } from '@hapi/joi';
import { injectable } from 'inversify';

@injectable()
export abstract class RequestValidator {
    protected validateRequest = (validationSchema: SchemaLike, request: Request, response: Response, next: NextFunction): void => {
        const validationResult: ValidationResult<Request> = joi.validate(request, validationSchema, {
            abortEarly: false
        });

        const { error }: { error: ValidationError } = validationResult;

        if (error) {
            response.status(400).json({
                message: 'The request validation failed.',
                details: error.details
            });
        } else {
            next();
        }
    }
}

接下来,我创建了一个派生 class,它创建了 validationSchema 并调用了 validateRequest 方法。为了简单起见,我将展示 "deleteUserById" 验证

import { Request, Response, NextFunction } from 'express';
import joi, { SchemaLike } from '@hapi/joi';
import { injectable } from 'inversify';

import { RequestValidator } from './RequestValidator';

@injectable()
export class UserRequestValidator extends RequestValidator {
    public deleteUserByIdValidation = async (request: Request, response: Response, next: NextFunction): Promise<void> => {
        const validationSchema: SchemaLike = joi.object().keys({
            params: joi.object().keys({
                id: joi.number().required(),
            })
        });

        this.validateRequest(validationSchema, request, response, next);
    }
}

重要说明: 我以这种方式创建 SchemaLike 因为某些路由可能有 params, body, query 需要在一个 运行 中进行验证.

调用路由时

DELETE /users/1

验证总是失败。我得到这个错误

UnhandledPromiseRejectionWarning: TypeError: joi_1.default.validate is not a function

每次验证都会出现错误,无论调用是否正确。有人知道如何解决吗?

使用express-joi-validation时遇到同样的问题。

如果您可以使用版本 15,降级 Joi 即可。

npm uninstall --save @hapi/joi
npm install --save @hapi/joi@15.0.3

您可以通过将 joi.validate(request, validationSchema 更改为 validationSchema.validate(request 来修复它,因为 v16 不再支持 joi.validate()。 API 文档和发行说明中清楚地记录了它。

与其降级 Joi 版本,不如快速查看最新版本的 API 并检查正确的使用方法。

Here 是目前 (16.1.7) 最新的 Joi API 的 link,您可以在其中看到使用 validate 的示例。

另外,为了确保您知道您使用的库的下一个版本中发生了什么变化,最好查看发行说明,here is a link to a Joi version 16 Release notes 在那里您可以看到所有 changes/new 功能,仅供参考,您可以查看有关 validate 方法的信息:

Remove Joi.validate() and Joi.describe() (call direct on schema instead) (#1941)

joi 的更新版本不适用于 Joi.validate(req.body,schema); 无需单独使用该对象。使用它如下。它对我很顺利。如果我有任何错误,请告诉我:

const Joi = require('@hapi/joi');

const schema = Joi.object({
    name:Joi.string().min(3).required(),
    email:Joi.string().min(4).required().email(),
    password:Joi.string().min(6).required()
});





router.post('/register', async (req,res) => {


    //updated joi
    
   // This is a shorter version
    const { error } = schema.validate(req.body);

    // Error in response

    res.send(error.details[0].message);


    // WORKING WITH DEPRECATED VERSION
    // const Validation = Joi.validate(req.body,schema);
    // res.send(Validation);

这里有一些固定的片段代码:)

在 npm 包下面安装。

npm install --save @hapi/joi@15.0.3

请求-validator.js文件

const Joi = require("@hapi/joi");

const registerValidation = data => {

const schema = {
    name : Joi.string().min(4).required(),
    email: Joi.string().min(4).required().email(),
    password: Joi.string().min(4).required()
};
return Joi.validate(data,schema);

}
module.exports.registerValidation = registerValidation;

最后,调用控制器中的验证方法。

const router = require("express").Router();
const {registerValidation}  = require("./req-validator")

router.post("/register",async(req,res)=> {

const {error} =  registerValidation(req.body);
if(error){
    return res.status(400).send(error.details[0].message);
}
 // logic to save in DB....
}

我经历过joi.validate()不是函数也。我检查了他们的文档并得到了修复。

    const Joi = require('@hapi/joi');

const schema = Joi.object({
    name:Joi.string().min(6).required(),
    email:Joi.string().min(6).required().email(),
    password:Joi.string().min(6).required()
});

router.post('/register',  (req, res) => {

    // VALIDATE BEFORE SAVING A USER 
    const Validation = schema.validate(req.body);
    res.send(Validation);

    
})

这按预期工作并且没有进一步的错误。

像这样创建你的验证函数

const validateUser = function (user) {
  const schema = Joi.object({
    username: Joi.string().min(5).max(50),
    email: Joi.string().required().email().min(5).max(255),
    password: Joi.string().required().min(5).max(1024),
  });

  return schema.validate(user);
};

你会得到错误

const { error } = validateUser({ email: 'admin' });

错误信息由

const message = error.details[0].message;

您可以通过更改来修复它 Joi.validate(request, validationSchema)validationSchema.validate(request) 因为 v16 不再支持 Joi.validate()

对于新版本

const schema = Joi.object({ name: Joi.string() .min(6) .required(),
email: Joi.string() .min(6) .required() .email(),
password: Joi.string() .min(6) .required() });

const validation = schema.validate(req.body);

// 获取模式定义的实例

function validate(model, object, scope) {
  const schema = getSchema(model, scope);
  return schema.validate(object);
}

// 要验证的实际中间件工厂

module.exports = function ValidationMiddleware(model, scope) {
  return (req, res, next) => {
    const validationResult = validate(model, req.body, scope);
    if (validationResult.error) {
      throw new Error(validationResult.error.details[0].message);
    } else {
      next();
    }
  };
};

使用这个

const schema = Joi.object({
    name: Joi.string().min(6).required(),
    email: Joi.string().min(6).email(),
    password: Joi.string().min(6).required()
})

替换为 const 模式 = {...}

并通过此验证:

const validate = schema.validate(req.body)

而不是 Joi.validate(req.body,schema)

只需检查您的文件中是否安装并需要@hapi/joi

并使用这种方法进行验证。

const schema= Joi.object().keys({

    name: Joi.string().min(6).required(),
    email: Joi.string().min(6).email(),
    password: Joi.string().min(6).required()
});

 const validation = schema.validate(req.body);
    if(validation.error){
        res.status(400).send(validation.error.details[0].message);
        return ;
    }

我认为这会奏效

对于新版本

const schema = Joi.object({ name: Joi.string() .min(6) .required(),
email: Joi.string() .min(6) .required() .email(),
password: Joi.string() .min(6) .required() });

const validation = schema.validate(req.body);
res.send(validation);

这是我正在使用 Joi 17.3.0 进行的项目中的直接内容:

PDFCreatorController.exportAsPDF = (req, res) => {
  const data = req.body
  const schema = Joi.object().keys({
    svgDataToExport: Joi.string().required()
  })
  const isValidPromise = new Promise((resolve) => {
    const validation = schema.validate(req.body)
    if (validation.error) {
      res.status(422).json({
        status: 'error',
        message: error,
        data: data
      })
    } else {
      resolve(data)
    }
  })
  isValidPromise.then(inputDataFromUser => {
    try {
      const exportAsPDF = PDFCreatorModel.exportAsPDF(inputDataFromUser)
      exportAsPDF.then(data => {
        res.json(data)
      })
    } catch (error) {
      console.error(error)
      return res.status(500).json(error)
    }
  })
}

由于 JOI 包的更新版本,我们都面临这个错误,但这是解决方案。在 Node.js 中,当我们遇到此错误时,我们可以应用以下解决方案来解决它。

// Example : Here we try to validate user's data
// User's POST Api 

const schema = Joi.object({
    name: Joi.string().min(1).required(),
    email:  Joi.string().required().email(),
    password: Joi.string().min(8).max(12).required(),
    isEmailVerified: Joi.boolean().required(),
    forgotPasswordToken: Joi.string().required(),
    isDeleted: Joi.boolean().required()
});
try {
    const value = await schema.validateAsync(req.body);
}
catch (err) {
    return res.status(400).send(err);
 }
Following works with the latest version ("@hapi/joi": "^17.1.1"):

    const Joi = require("@hapi/joi");

    const schema = Joi.object({
      name: Joi.string().min(6).required(),
      email: Joi.string().min(6).required().email(),
      password: Joi.string().min(6).required(),
    });
    
  router.post("/register", async (req, res) => {
  const { error } = schema.validate(req.body);

  if (error) {
    res.json({ ErrorMessage: error.details[0].message });
  } else {
    res.json({ message: "valid data" });
  }

});

降低joi的版本。到 13.0.1 它将起作用。 在终端 npm i joi@13.0.1。 2.after 安装检查。包中的依赖项。 Json 文件。

npm i joi

joi v17.4.x 资源:https://joi.dev/api/?v=17.4.2

const schema = Joi.object({
  email: Joi.string().email().required(),
  password: Joi.string().required().min(5),
});

 const result = schema.validate(YourRequest.body);