使用Yii 2获取有关Ajax调用的错误请求(#400)

时间:2014-11-25 11:54:34

标签: jquery ajax yii2

这是我的代码:

$(document).on('change', '#tblhotel-int_zone_id', function(e){
    var zoneId = $(this).val();
    var form_data = {
        zone: zoneId
    };
    $.ajax({
        url: "state",
        type: "POST",
        data: form_data,
        success: function(response)
        {
            alert(response);
        }
    });
});

这表明:

  

错误请求(#400):无法验证您的数据提交。

我已经<?= Html::csrfMetaTags() ?>了。我该如何解决这个问题?

8 个答案:

答案 0 :(得分:39)

注意:请参阅the answer from Skullcrasher以正确的方式解决问题,因为我的回答建议禁用Cross-Site Request Forgery


您的enableCsrfValidation存在问题。要阅读更多相关信息,请阅读here

要禁用CSRF,请将此代码添加到控制器:

public function beforeAction($action) {
    $this->enableCsrfValidation = false;
    return parent::beforeAction($action);
}

这将禁用所有操作。您可能应该根据$操作禁用它,仅用于特定操作。

答案 1 :(得分:26)

正如Mihai P.所说,你的问题是CSRF验证。您也可以禁用对您的操作进行验证,但这不是一个好的解决方案。

由于您的Ajax请求中存在验证问题,您还可以使用Yii JavaScript函数将CSRF令牌添加到您在Ajax请求中发送的formdata。

只需尝试将令牌添加到表单数据中,如下所示:

var form_data = {
    zone: zoneId,
    _csrf: yii.getCsrfToken()
};

我希望这会有所帮助,因此您不必禁用CSRF验证。

除了手动添加CSRF令牌外,您还可以检查请求中是否设置了X-CSRF标头。

答案 2 :(得分:8)

在布局的底部添加此代码:

<script>
    $.ajaxSetup({
        data: <?= \yii\helpers\Json::encode([
            \yii::$app->request->csrfParam => \yii::$app->request->csrfToken,
        ]) ?>
    });
</script>

答案 3 :(得分:5)

使用:

var csrfToken = $('meta[name="csrf-token"]').attr("content");
$.ajax({
    url: 'request',
    type: 'post',
    dataType: 'json',
    data: {param1: param1, _csrf : csrfToken},
});

更多详情: Yii2: Using csrf token

答案 4 :(得分:2)

您需要在行动前功能中禁用CSRF验证:

public function beforeAction($action) {
    if($action->id == "action name need to disable")
        $this->enableCsrfValidation = false;
    return parent::beforeAction($action);
}

或使用GET method

答案 5 :(得分:1)

这很有效。用你自己的csrfParam更改 在Config / main.php中

'components' => [
    'request'=>[
        'csrfParam'=>"othername"
    ],
    ...

请记住,您必须在请求中包含与您在config中定义的名称相同的令牌。

答案 6 :(得分:0)

/backend/config/main-local.php

'components' => [
    'request' => [
        'cookieValidationKey' => 'unique code',
        'csrfCookie' => ['httpOnly' => true, 'path' => '/admin/'],
    ],
],

/frontend/config/main-local.php

'components' => [
    'request' => [
        'cookieValidationKey' => 'unique code',
        'csrfCookie' => ['httpOnly' => true, 'path' => '/'],
    ],
],

答案 7 :(得分:0)

尽管这是一本有很多答案的旧文章,但所有已发布的答案中都缺少一些内容,它们都解决了正确的问题,但是当调用ajax POST请求以及您的数据时,您应该使用提供了yii.js个功能

  • yii.getCsrfParam()获取令牌的参数名称
  • yii.getCsrfToken()获取令牌或csrf令牌的实际值

好像您在config.php组件配置下的web.phprequest内为前端定义了不同的参数名

components=>[
.......
.......
    'request' => [
        'csrfParam' => '_csrf-frontend',
    ],
.......
.......
]

然后您需要动态获取该名称,以上功能可以帮助您。

您应该

var form_data = {
    zone: zoneId
};
form_data[yii.getCsrfParam()]=yii.getCsrfToken();