Yii2中AJAX表单提交失败时需在控制器捕获验证错误、手动构造错误数组并返回JSON响应,前提是模型已正确定义验证规则。

在 Yii2 中,表单提交失败后返回验证错误的 JSON 数据,常用于 AJAX 提交场景。关键在于:控制器中捕获模型验证失败、手动构造错误数组、并以 JSON 格式响应。
1. 模型定义(含验证规则)
确保模型类(如 UserForm)已正确定义验证规则:
<?php
namespace app\models;
use yii\base\Model;
class UserForm extends Model
{
public $username;
public $email;
public $password;
public function rules()
{
return [
[['username', 'email'], 'required'],
['username', 'string', 'min' => 2, 'max' => 20],
['email', 'email'],
['password', 'string', 'min' => 6],
];
}
public function attributeLabels()
{
return [
'username' => '用户名',
'email' => '邮箱',
'password' => '密码',
];
}
}
2. 控制器中处理 AJAX 请求并返回错误 JSON
在控制器动作中,实例化模型、加载数据、验证,并在失败时返回结构清晰的错误信息:
<?php
namespace app\controllers;
use app\models\UserForm;
use yii\web\Controller;
use yii\web\Response;
class SiteController extends Controller
{
public function actionSignup()
{
\Yii::$app->response->format = Response::FORMAT_JSON;
$model = new UserForm();
$model->load(\Yii::$app->request->post(), '');
if ($model->validate()) {
// 验证通过,执行注册逻辑(略)
return ['success' => true, 'message' => '注册成功'];
} else {
// 验证失败,返回错误字段及第一条错误消息(或全部)
$errors = [];
foreach ($model->getErrors() as $attribute => $msgs) {
$errors[$attribute] = $msgs[0]; // 取第一个错误提示(常用)
// 或用:$errors[$attribute] = $msgs; // 返回全部错误数组
}
return [
'success' => false,
'errors' => $errors,
'message' => '请检查表单输入'
];
}
}
}
3. 前端 AJAX 提交与错误显示示例
使用 jQuery 提交并处理返回的 JSON 错误:
$('#signup-form').on('submit', function (e) {
e.preventDefault();
$.post($(this).attr('action'), $(this).serialize())
.done(function (res) {
if (res.success) {
alert(res.message);
location.href = '/site/index';
} else {
// 清除旧错误
$('.error-message').remove();
// 显示新错误
$.each(res.errors, function (field, msg) {
var $input = $('[name="' + field + '"]');
var $group = $input.closest('.form-group');
$group.append('<div class="error-message text-danger">' + msg + '</div>');
});
}
})
.fail(function () {
alert('请求失败,请重试');
});
});
4. 补充说明
注意以下细节可避免常见问题:
- 务必设置
\Yii::$app->response->format = Response::FORMAT_JSON,否则可能触发 HTML 渲染 -
$model->load(..., '')中第二个参数为空字符串,避免默认前缀(如UserForm[username])导致无法绑定 - 若需返回所有错误(不止第一条),可将
$msgs[0]改为$msgs,此时前端需遍历数组展示 - 建议统一响应结构(如始终含
success、errors、message字段),便于前端统一处理


















