You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Joi校验接口参数报错joi.validate is not a function如何解决

问题原因

joi.validate is not a function 报错是因为你使用的是 Joi v16及以上版本,这个版本开始官方移除了全局静态方法Joi.validate(),你后续尝试的Joi.schema(ctx.request.body)属于错误写法,Joi本身不存在schema这个全局方法。

正确修复方案

Joi新版本的校验逻辑调整为:先定义校验规则schema实例,再调用schema实例上的validate方法传入待校验数据,对应你代码里的校验部分修正如下:

exports.localLogin = async (ctx) => {
    // 定义校验规则,新版本Joi.object()可直接传入规则对象,无需链式调用keys()
    const schema = Joi.object({
        email: Joi.string().email().required(),
        password: Joi.string().required()
    });

    // 调用schema实例的validate方法做校验,而非全局Joi.validate
    const { error, value: validParams } = schema.validate(ctx.request.body, {
        abortEarly: false, // 可选,设为false会返回所有参数的校验错误,默认碰到第一个错误就终止
        allowUnknown: false // 可选,设为true允许请求体携带未定义的字段,默认false
    });

    if(error) {
        ctx.status = 400; // Bad Request
        // 可选:把具体校验错误信息返回给前端
        ctx.body = {
            msg: error.details.map(item => item.message).join('; ')
        };
        return;
    }

    // 校验通过后,优先使用校验返回的validParams,避免直接使用原始请求体带来的多余字段/类型异常问题
    const { email, password } = validParams; 

    let account = null;
    try {
        account = await Account.findByEmail(email);
    } catch (e) {
        ctx.throw(500, e);
    }

    if(!account || !account.validatePassword(password)) {
        ctx.status = 403; // Forbidden
        return;
    }

    ctx.body = account.profile;
};
额外注意点
  • 如果你确实需要使用老的Joi.validate()写法,需要把本地安装的Joi降级到v15及以下版本,执行npm i joi@15即可,但更推荐使用新版本API。
  • 不要照搬发布时间过早的Joi教程,v16之后属于大版本迭代,核心校验API的调用方式变化很大,老教程的写法在新版本里基本都无法运行。

内容的提问来源于stack exchange,提问作者JIHYEON

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 13:36:18