Yii2 AJAX表单验证失败时应返回JSON错误信息,需在控制器中手动调用validate()并用getErrors()获取字段级错误,设置422状态码返回标准化结构;全局配置可通过基类beforeAction拦截实现,前端可据此映射DOM元素显示错误。

Yii2 表单验证失败时,默认会返回 HTML 页面或触发客户端 JavaScript 错误提示。若需在 AJAX 提交场景下统一返回 JSON 格式的错误信息(如 {"name": ["姓名不能为空"], "email": ["邮箱格式不正确"]}),关键在于捕获模型验证失败后的错误,并手动构造响应结构。
在控制器中统一处理验证失败的 JSON 响应
推荐在控制器动作中显式判断模型是否有效,避免依赖 Yii 自动渲染。验证失败时调用 yii\web\Response::setStatusCode() 并返回标准化 JSON 数据:
- 调用
$model->load(Yii::$app->request->post())加载数据 - 用
$model->validate()手动触发验证(不依赖save()) - 若验证失败,使用
$model->getErrors()获取字段级错误数组 - 设置响应状态码为 422(Unprocessable Entity)更语义化
示例代码:
public function actionCreate()
{
$model = new Article();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->save();
return ['success' => true, 'data' => $model->attributes];
}
Yii::$app->response->setStatusCode(422);
return [
'success' => false,
'errors' => $model->getErrors(), // 已是 ['field' => ['msg1', 'msg2']] 结构
];
}
全局配置:让所有验证失败自动转 JSON(适用于 RESTful 场景)
若项目以 API 为主,可在 config/web.php 中配置 response 组件,并结合 beforeAction 统一拦截:
- 在控制器基类(如
ApiController)中重写beforeAction() - 检测请求是否为 AJAX 或指定格式(如
application/json) - 捕获
Model::validate()后的错误,替换默认行为 - 注意:不要覆盖
ActiveForm的普通表单提交逻辑,否则影响非 AJAX 场景
前端接收与解析建议
JavaScript 接收响应后,可直接遍历 errors 字段并绑定到对应表单项:
- 使用 jQuery 或原生
fetch检查响应状态码是否为 422 - 将
errors对象映射为 DOM 元素的data-field属性或 name 名称 - 清空旧提示、插入新错误文本(支持多条错误合并显示)
- 示例:
Object.keys(data.errors).forEach(field => console.log(field, data.errors[field][0]))
补充:自定义错误格式(如扁平化或带 code 字段)
如需兼容第三方接口规范,可在返回前转换错误结构:
$errors = [];
foreach ($model->getErrors() as $field => $messages) {
foreach ($messages as $message) {
$errors[] = [
'field' => $field,
'message' => $message,
'code' => 'validation_failed'
];
}
}
return ['success' => false, 'errors' => $errors];
这种格式更适合前端做统一错误 toast 或日志上报。


















