joi_1.default.validate 不是函数

Posted

技术标签:

【中文标题】joi_1.default.validate 不是函数【英文标题】:joi_1.default.validate is not a function 【发布时间】:2020-01-17 06:38:34 【问题描述】:

我想在调用控制器逻辑之前验证我的 Express 路由。我使用 joi 并创建了一个验证器,它能够针对架构对象验证 Request 对象

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();
        
    

接下来我创建了一个派生类,它创建了 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 需要在一次运行中得到验证。

调用路由时

删除 /users/1

验证总是失败。我收到此错误

UnhandledPromiseRejectionWarning: TypeError: joi_1.default.validate 是 不是函数

无论调用是否正确,每次验证都会发生错误。有人知道怎么解决吗?

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

更新版本的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);

【讨论】:

【参考方案3】:

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

如果你可以使用版本 15,降级 Joi 就可以了。

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

【讨论】:

对不起,投反对票,因为这不再是实际的了。 v15 已弃用。 API 已更改。检查 Eran Hammer 的答案,这是正确的。 否决它。您不应该使用已弃用的 API。【参考方案4】:

我体验过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);

    
)

这按预期工作,不会再出现错误。

【讨论】:

【参考方案5】:

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

对于新版本

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);

【讨论】:

【参考方案6】:

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

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

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

删除 Joi.validate() 和 Joi.describe() (改为直接调用架构)(#1941)

【讨论】:

这个答案有效。在模式中放 const schemaName= Joi.object( 然后你的正常模式数据:注意 Joi.object 是需要的。调用它时,只需使用 schemaName.validate(req.body) [而不是旧版本 Joi.validate( req.body, schemaName)]【参考方案7】:

对于新版本

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);

【讨论】:

【参考方案8】:

这里有一些用 sn-p 固定的代码:)

安装在 npm 包下面。

npm install --save @hapi/joi@15.0.3

req-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....

【讨论】:

【参考方案9】:

您只需检查您的文件中是否安装了@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 ;
    

我认为这行得通

【讨论】:

【参考方案10】:
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" );
  

);

【讨论】:

【参考方案11】:

像这样创建您的验证函数

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;

【讨论】:

【参考方案12】:

// 获取模式定义上的实例

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();
    
  ;
;

【讨论】:

虽然此代码可能会回答问题,但仅代码答案对于此问题的未来访问者的用处有限。考虑编辑一些关于您的代码如何和/或为什么回答问题的解释。【参考方案13】:

使用这个

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

insted of const schema = ...

并通过此验证:

const validate = schema.validate(req.body)

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

【讨论】:

【参考方案14】:

这是我正在使用 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)
    
  )

【讨论】:

【参考方案15】:

由于 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);
 

【讨论】:

【参考方案16】:

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

【讨论】:

这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review【参考方案17】:

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);

【讨论】:

您的格式让我非常困惑,以至于我无法判断这是仅代码还是“测试”随机字符帖子。让我们假设只有代码。 虽然此代码可能会解决问题,但 including an explanation 关于如何以及为何解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的答案添加解释并说明适用的限制和假设。 链接的内容不被视为答案的一部分,因此这仍然是仅代码。并且不可读或格式混乱。请写一些带有解释的散文,并尝试更严肃的格式。 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于joi_1.default.validate 不是函数的主要内容,如果未能解决你的问题,请参考以下文章

Nodejs - Joi 检查字符串是不是在给定列表中

题解[JOI Open 2021] Crossing

2018.9.20JOI 2017 Final T2「準急電車 / Semiexpress」

将 Joi 模式与 Mongoose 模式一起使用?

2018.9.20JOI 2017 Final T3「JOIOI 王国 / The Kingdom of JOIOI」

OS用法详解os.path.abspath(__file__)&os.path.dirname()&os.path.basename(__file__)&os.path.joi