Yii2 AJAX表单验证需手动触发模型验证并返回标准化JSON响应:控制器中调用load()和validate(),清空旧错误,检查hasErrors(),用getErrors()构造{code:422,message:"验证失败",errors:{}}结构;前端用updateAttribute注入错误。

Yii2 的 ActiveForm 默认提交失败时会刷新页面并显示错误,但 AJAX 提交需要返回结构化 JSON 响应,便于前端统一处理。关键在于拦截默认验证流程、手动触发模型验证,并按约定格式输出错误信息。
确保模型验证通过且收集错误
在控制器中接收表单数据后,先用 $model->load() 绑定属性,再调用 $model->validate() 主动触发验证。不要依赖 save() 的自动验证,因为 save 可能因其他原因失败(如数据库约束),干扰错误定位。
- 验证前清空可能残留的旧错误:
$model->clearErrors(); - 验证后检查
$model->hasErrors()判断是否出错 - 用
$model->getErrors()获取完整错误数组,它返回形如['username' => ['用户名不能为空']]的结构
构造符合前端预期的 JSON 响应
推荐返回包含状态码、消息和错误详情的标准化结构,例如:
{ "code": 422, "message": "验证失败", "errors": { "username": ["用户名不能为空"], "email": ["邮箱格式不正确"] } }在控制器中可这样写:
if ($model->hasErrors()) {
return $this->asJson([
'code' => 422,
'message' => '验证失败',
'errors' => $model->getErrors(),
]);
}
前端接收并注入 ActiveForm 错误
使用 jQuery 的 $.post 或 $.ajax 提交后,在 error 或 success 回调中解析响应。若后端返回 422 状态或自定义 code,需手动将错误映射到对应字段:
- 遍历
response.errors,对每个字段名拼接#form-id-attribute-name选择器 - 调用
$form.yiiActiveForm('updateAttribute', attribute, errors)注入错误 - 确保表单已初始化 Active Form(即已执行
$form = $('#my-form').yiiActiveForm(...))
示例片段:
$.post($form.attr('action'), $form.serialize()).done(function(response) {
if (response.code === 422) {
$.each(response.errors, function(attribute, messages) {
$form.yiiActiveForm('updateAttribute', attribute, messages);
});
}
});
补充:禁用客户端重复验证(可选)
如果后端是唯一验证入口,可在 ActiveForm 配置中关闭 JS 验证,避免前后端规则不一致:
$form = ActiveForm::begin([
'enableClientValidation' => false,
'enableAjaxValidation' => false,
]);
这样所有验证逻辑集中于后端,JSON 响应也更可控。











