Yii2 GridView点击按钮改订单状态仅传CSRF令牌,数据未提交问题
问题分析与解决方案
嘿,我一眼就看出问题所在了——你的按钮没有传递任何业务相关的参数(比如订单ID、要修改的状态值),而且URL生成也没带上必要的标识,所以POST请求里自然只有CSRF令牌啦。下面一步步给你改:
核心问题点
- 你的
urlCreator只是返回了固定的'contracts'路径,没有把当前订单的ID和操作类型(确认/拒绝)传递给控制器 - 按钮的
data-method="post"只会自动提交CSRF令牌,不会主动把模型数据带过去,得手动指定要传递的参数
具体修改步骤
1. 修正GridView的ActionColumn配置
首先要在按钮里添加data-params来传递订单ID和目标状态,同时修正urlCreator生成正确的路由(虽然POST请求里参数主要靠data-params,但路由还是要正确指向控制器方法):
['class' => 'yii\grid\ActionColumn', 'template' => "{confirm} {decline}", 'buttons' => [ 'confirm' => function ($url, $model) { return Html::a('<span class="glyphicon glyphicon-ok"></span>', $url, [ 'title' => Yii::t('yii', 'confirm'), 'data-confirm' => Yii::t('yii', 'Сдать авто?'), 'data-method' => 'post', 'data-pjax' => 1, // 这里添加要传递的POST参数 'data-params' => [ 'id' => $model->id, // 订单ID 'new_stat' => 1 // 建议用数字标识状态,比如1=已确认,0=已拒绝 ] ]); }, 'decline' => function ($url, $model) { return Html::a('<span style="color: red" class="glyphicon glyphicon-remove"></span>', $url, [ 'title' => Yii::t('yii', 'decline'), 'data-confirm' => Yii::t('yii', 'Отказ?'), 'data-method' => 'post', 'data-pjax' => 2, 'data-params' => [ 'id' => $model->id, 'new_stat' => 0 ] ]); } ], 'urlCreator' => function ($action, $model, $key, $index) { // 生成带订单ID的路由,确保控制器能识别是哪个订单的操作 return \yii\helpers\Url::to(['contracts', 'id' => $model->id]); } ],
2. 修正控制器方法
现在你就能在控制器里拿到POST过来的参数了,建议用Yii的请求对象来获取,比直接用$_POST更规范:
public function actionContracts() { if(Yii::$app->request->isPost) { $id = Yii::$app->request->post('id'); $newStat = Yii::$app->request->post('new_stat'); // 这里写你的状态修改逻辑,比如: // $model = Contract::findOne($id); // if ($model) { // $model->status = $newStat; // $model->save(false); // 根据需求决定是否验证 // } print_r(Yii::$app->request->post()); die(); } }
为什么原来的代码不行?
Yii的data-method="post"是通过JavaScript把a标签转换成POST表单提交的,但默认只会包含CSRF令牌。如果要传递额外参数,必须通过data-params指定,这样JS会把这些参数加到表单的隐藏域里,一起提交到服务器。另外,你的urlCreator之前没有传递订单ID,就算拿到POST请求,也不知道要修改哪个订单的状态对吧?
内容的提问来源于stack exchange,提问作者Andreykin Sergey
相关产品推荐
相关产品推荐

