yii2表单post提交json时验证失败需统一返回标准json错误结构:{"error":true,"messages":{"username":["用户名不能为空"]}},并预处理字段名、前端安全解析。

Yii2 表单通过 POST 提交 JSON 数据时,若验证失败,默认返回的错误信息是 PHP 数组格式(如 ['username' => ['用户名不能为空']]),前端无法直接解析为标准 JSON 错误结构,容易导致 JS 解析异常或 UI 展示错乱。关键在于统一后端响应格式,并确保验证错误能被正确序列化为前端友好的 JSON 对象。
确保请求头和数据格式正确
前端发送时需设置:
- Content-Type: application/json(告诉 Yii 启用 JSON 输入解析)
- 使用
JSON.stringify()发送数据,例如:{ "username": "", "email": "test" }
Yii2 默认会自动调用 Yii::$app->request->getBodyParams() 并尝试解析 JSON(需开启 enableCsrfValidation = false 或正确传递 CSRF token)。
重写控制器中的验证错误响应逻辑
不要直接返回 $model->getErrors(),而应手动构造结构化 JSON 响应:
if ($model->load(Yii::$app->request->bodyParams, '') && $model->validate()) {
return $this->asJson(['success' => true, 'data' => $model->attributes]);
} else {
// 统一错误格式:{ "error": true, "messages": { "username": ["用户名不能为空"], "email": ["邮箱格式不正确"] } }
return $this->asJson([
'error' => true,
'messages' => $model->getErrors(),
]);
}
处理嵌套模型或自定义验证字段名
若使用 formName() 或嵌套属性(如 UserProfile[phone]),getErrors() 返回的键可能含方括号,前端解析不便。建议预处理字段名:
- 用正则或
str_replace(['[', ']'], ['', '.'], $key)标准化键名 - 或在 Model 中重写
formName()返回空字符串,使属性直连(适合 API 场景) - 对多维错误(如文件上传、数组字段),用
ArrayHelper::getColumn($model->getErrors(), 'username', [])提取特定字段
前端接收并安全解析错误信息
JS 中应检查响应结构再读取,避免 res.messages.username[0] 报错:
fetch('/user/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
.then(r => r.json())
.then(res => {
if (res.error && res.messages) {
Object.keys(res.messages).forEach(field => {
const msgs = Array.isArray(res.messages[field])
? res.messages[field]
: [res.messages[field]];
console.log(field, msgs[0]); // 显示第一个错误
});
}
});











