Web

Несоответствие токена csrf laravel для запроса POST ajax

Я пытаюсь удалить данные из базы данных через ajax.

HTML:

@foreach($a as $lis)

  //некоторый код

  <a href="#" class="delteadd" id="{{$lis['id']}}">Delete</a>

  // действие клика выполняется по этой ссылке                  

@endforeach

 Мой код ajax:

$('body').on('click', '.delteadd', function (e) {

e.preventDefault();

//alert('am i here');

if (confirm('Вы уверены что хотите выполнить удаление ?')) {

    var id = $(this).attr('id');

    $.ajax({

        method: "POST",

        url: "{{url()}}/delteadd",

        }).done(function( msg ) {

        if(msg.error == 0){

            //$('.sucess-status-update').html(msg.message);

            alert(msg.message);

        }else{

            alert(msg.message);

            //$('.error-favourite-message').html(msg.message);

        }

    });

} else {

    return false;

}

});

 Это мой запрос на получение данных из базы данных...

$a = Test::with('hitsCount')->where('userid', $id)->get()->toArray();

 Но, когда я нажимаю «Удалить данные ссылки», они не удаляются и показывают несоответствие csrf_token... Что я делаю неправильно?

 

 Ответ 1

Лучший способ решить проблему «X-CSRF-TOKEN» это добавить следующий код в ваш основной макет и продолжить выполнять обычные вызовы ajax:

В заголовке

<meta name="csrf-token" content="{{ csrf_token() }}" />

 В сценарии

<script type="text/javascript">

$.ajaxSetup({

    headers: {

        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')

    }

});

</script>

 

 Ответ 2

Необходимо добавить headers: в вызове ajax:

  headers: {‘X-CSRF-TOKEN’: $(‘meta[name=”csrf-token”]’).attr(‘content’)},

Я имею в виду:

<div id = 'msg'>

     Это сообщение будет изменено с помощью Ajax. Нажмите кнопку, чтобы изменить сообщение.

</div>

 {{ Form::submit('Change', array('id' => 'ajax')) }}

 Функция ajax:

<script>

 $(document).ready(function() {

    $(document).on('click', '#ajax', function () {

      $.ajax({

         type:'POST',

         url:'/ajax',

         headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},

         success:function(data){

            $("#msg").html(data.msg);

         }

      });

    });

});

</script>

 Контроллер:

public function call(){

    $msg = "This is a simple message.";

    return response()->json(array('msg'=> $msg), 200);

}

 routes.php

Route::post('ajax', 'AjaxController@call');

 

Ответ 3

Если вы используете файлы шаблонов, вы можете поместить свой meta-тег в заголовок section (или как вы его называете), который содержит ваши meta-теги:

@section('head')

<meta name="csrf_token" content="{{ csrf_token() }}" />

@endsection

 Далее вам нужно поместить атрибут headers в свой ajax (в моем примере я использую datatable обработку на стороне сервера):

"headers": {'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')}

Вот полный datatable пример ajax:

$('#datatable_users').DataTable({

        "responsive": true,

        "serverSide": true,

        "processing": true,

        "paging": true,

        "searching": { "regex": true },

        "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],

        "pageLength": 10,

        "ajax": {

            "type": "POST",

            "headers": {'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')},

            "url": "/getUsers",

            "dataType": "json",

            "contentType": 'application/json; charset=utf-8',

            "data": function (data) {

                console.log(data);

            },

            "complete": function(response) {

                console.log(response);

           }

        }

    });

 После этого вы должны получить 200 status по вашему ajax запросу.

 

Ответ 4

Знайте, что для удобства установлен файл cookie в «X-XSRF-TOKEN». Фреймворки, такие как Angular и другие, устанавливают его по умолчанию. Посмотрите это в документе:

https://laravel.com/docs/5.7/csrf#csrf-x-xsrf-token.

Возможно, вы захотите его использовать. Лучше всего использовать метатег, если файлы cookie отключены:

    var xsrfToken = decodeURIComponent(readCookie('XSRF-TOKEN'));

    if (xsrfToken) {

        $.ajaxSetup({

            headers: {

                'X-XSRF-TOKEN': xsrfToken

            }

        });

    } else console.error('....');

 Вот рекомендуемый мета-способ (вы можете указать поле любым способом, но мета-метод довольно надежный):

$.ajaxSetup({

    headers: {

        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')

    }

});   

 Обратите внимание на использование decodeURIComponent(), он декодируется из формата uri, который используется для хранения файла cookie [в противном случае вы получите исключение недопустимой полезной нагрузки в laravel].

Также laravel (bootstrap.js) по умолчанию устанавливает его для axios:

let token = document.head.querySelector('meta[name="csrf-token"]');

 if (token) {

    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;

} else {

    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');

 И далее используйте функцию cookie:

   function readCookie(name) {

        var nameEQ = name + "=";

        var ca = document.cookie.split(';');

        for (var i = 0; i < ca.length; i++) {

            var c = ca[i];

            while (c.charAt(0) == ' ') c = c.substring(1, c.length);

            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);

       }

        return null;

    }

 

Ответ 5

Если вы используете jQuery для отправки сообщений AJAX, добавьте этот код во все представления:

$( document ).on( 'ajaxSend', addLaravelCSRF );

 function addLaravelCSRF( event, jqxhr, settings ) {

    jqxhr.setRequestHeader( 'X-XSRF-TOKEN', getCookie( 'XSRF-TOKEN' ) );

}

 

function getCookie(name) {

    function escape(s) { return s.replace(/([.*+?\^${}()|\[\]\/\\])/g, '\\$1'); };

    var match = document.cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));

    return match ? match[1] : null;

}

Laravel добавляет файл cookie XSRF ко всем запросам, и мы автоматически добавляем его ко всем запросам AJAX непосредственно перед отправкой.

Вы можете заменить функцию getCookie, если есть другая функция или плагин jQuery, делающие то же самое.

 

 Ответ 6

Для Laravel 5.8 установка метатега csrf для вашего макета и установка заголовка запроса для csrf в настройках ajax не будут работать, если вы используете ajax для отправки формы, которая уже включает _token поля ввода, созданный механизмом создания шаблонов Laravel blade.

Вы должны включить уже сгенерированный токен csrf из формы с вашим запросом ajax, потому что сервер будет ожидать его, а не тот, который указан в вашем метатеге.

Например, так выглядит _token поля ввода, созданный в Blade:

<form>

    <input name="_token" type="hidden" value="cf54ty6y7yuuyyygytfggfd56667DfrSH8i">

    <input name="my_data" type="text" value="">

    <!-- other input fields -->

</form>

 Затем вы отправляете свою форму с помощью ajax следующим образом:

<script> 

    $(document).ready(function() { 

        let token = $('form').find('input[name="_token"]').val();

        let myData = $('form').find('input[name="my_data"]').val();

        $('form').submit(function() { 

            $.ajax({ 

                type:'POST', 

                url:'/ajax', 

                data: {_token: token, my_data: myData}

                // headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}, // другие настройки ajax

            }); 

            return false;

        }); 

    }); 

</script>

 Токен csrf в мета-заголовке полезен только тогда, когда вы отправляете форму без _token поля ввода, созданного в Blade.

 

Схожие статьи

Web

isset() и empty() - что лучше использовать?

Тестирование и оптимизация скорости работы сайта: необходимые инструменты и применение
Web

Тестирование и оптимизация скорости работы сайта: необходимые инструменты и применение

Web

Почему происходит «Неопределенная переменная/индекс/смещение» в PHP

Web

Когда использовать self вместо $this?

×