yii2 ajax表单验证失败时默认返回200状态码,应手动设为422;推荐在控制器中验证失败后调用setstatuscode(422)再返回json错误;restful api中activecontroller已自动处理。

Yii2 表单验证返回 JSON 响应时,默认 HTTP 状态码是 200,即使验证失败(如返回 {"name":["Name cannot be blank."]})。但前端常需靠状态码区分成功/失败(比如 422 Unprocessable Entity 更符合语义),这时需手动设置状态码。
在控制器中统一设置 422 状态码(推荐)
当使用 $model->load() + $model->validate() 进行 AJAX 表单验证时,在验证失败后显式设置响应状态:
- 调用
\Yii::$app->response->setStatusCode(422); - 确保在
return $this->asJson(...)之前执行 - 完整示例:
public function actionCreate()
{
$model = new Post();
if ($model->load(\Yii::$app->request->post()) && $model->validate()) {
$model->save();
return $this->asJson(['success' => true]);
} else {
\Yii::$app->response->setStatusCode(422);
return $this->asJson($model->errors);
}
}
全局拦截验证失败并设状态码(进阶)
若项目多处使用 AJAX 验证,可借助 beforeAction 或自定义行为统一处理:
- 重写控制器的
beforeAction(),检查是否为 AJAX 请求且模型验证失败 - 或创建一个
JsonValidationBehavior,监听Model::EVENT_AFTER_VALIDATE - 注意:仅对主动调用
validate()的场景生效,save()内部验证需额外处理
配合 RESTful 风格 API(如使用 yii2-rest)
若基于 yii\rest\ActiveController,框架默认在验证失败时已返回 422 状态码(通过 yii\rest\Serializer::serialize() 触发),无需手动设置。但需确认:
- 控制器继承自
ActiveController(非普通Controller) - 未覆盖
actions()中的create/update行为 - 请求头包含
Accept: application/json











