Получение неверного запроса (№ 400) на Ajax-вызовы с использованием Yii 2

Это мой код:

$(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() ?>. Как я могу исправить эту проблему?

Ответы

Ответ 1

У вас есть проблема с enableCsrfValidation. Чтобы узнать больше об этом вы можете прочитать здесь.

Чтобы отключить CSRF, добавьте этот код в свой контроллер:

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

Это отключит все действия. Возможно, вам следует, в зависимости от $ action, отключить его только для определенных действий.

Примечание. Смотрите ответ от Skullcrasher, чтобы сделать это более правильно.

Ответ 2

Как следует из ответа Михая П., ваша проблема заключается в проверке CSRF. Также верно, что вы можете отключить проверку своих действий, но это не считается хорошим решением.

Поскольку у вас есть проблема в вашем запросе Ajax с проверкой, вы также можете использовать функцию JavaScript Yii, чтобы добавить токен CSRF в ваши данные формы, которые вы отправляете в запросе Ajax.

Просто попробуйте добавить токен в данные формы следующим образом:

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

Я надеюсь, что это поможет, и поэтому вам не нужно отключать проверку CSRF.

В дополнение к ручному добавлению маркера CSRF вы можете проверить, есть ли в запросе заголовок X-CSRF.

Ответ 3

Добавьте этот код в нижней части вашего макета:

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

Ответ 4

Использование:

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

Подробнее: Yii2: Использование токена csrf

Ответ 5

Вам нужно отключить проверку CSRF в функции перед действием:

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

Или используя метод GET.

Ответ 6

Это работает. Измените csrfParam на свой собственный в Config/main.php

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

Помните, что вы должны включить в свои запросы токен с тем же именем, что и в config.

Ответ 7

/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' => '/'],
    ],
],

Ответ 8

Хотя это старый пост с множеством ответов, но во всех опубликованных ответах чего-то не хватает, все они обращены к правильному пункту, но при вызове запроса ajax POST вместе с вашими данными вы должны использовать yii.js функции yii.js

  • yii.getCsrfParam() чтобы получить имя параметра токена
  • yii.getCsrfToken() для получения токена или фактического значения csrf-токена

Как если бы у вас было другое имя параметра для web.php интерфейса, определенного в config.php или web.php в конфигурациях компонентов request вам нужно получить это имя динамически, и вышеуказанная функция поможет вам.

Вам следует

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