You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:33:00