419 при отправке живых форм отображается через толкатель - PullRequest
1 голос
/ 12 июня 2019

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

Пример: игрок A посылает вызов игроку B. PlayerB может принять или отклонить этот вызов. Как только игрок A отправляет запрос игроку B, я обновляю веб-страницу (вошедшую в систему как игрок B) и вижу вызов игрока Player. Теперь я могу принять или отклонить этот вызов, и все работает хорошо.

Теперь, когда playerA создает вызов, я запускаю событие в контроллере, которое автоматически отображает вызов playerB через толкатель без необходимости обновления страницы. Поэтому, как только playerA отправляет вызов playerB, playerB теперь может увидеть этот вызов, не обновляя страницу. Пока все работает хорошо.

Теперь проблемы начинаются. Если playerB пытается отклонить или принять вызов (который появился через толкателя), страница перенаправляется и отображает ошибку 419. Если playerB обновит страницу, вызов может быть отклонен или принят как обычно. Проблема возникает только тогда, когда игрок отвечает на вызов, который был показан через толкателя. Если запрос загружается через обновление страницы, формы будут работать нормально.

Вот так выглядит часть моего кода для отображения формы вызова отклонения через толкатель:

var receivedChallengesWrapper   = $('#kt_tabs_5_3');
var receivedChallenges          = receivedChallengesWrapper.find('.kt-portlet__body');

Pusher.logToConsole = true;
var pusher = new Pusher('XXXXXXXXX', {
    authEndpoint: 'pusher/auth',
    auth: 
    {
        headers: 
           {
                'X-CSRF-Token': '{{ csrf_token() }}'
       }
    },
    cluster: 'eu',
    encrypted: false
});

var privatechannel = pusher.subscribe('private-receivedChallenges-{{ Auth::user()->id }}');

privatechannel.bind('receivedChallenges', function(data) 
{
var existingReceivedChallenges  = receivedChallenges.html();
var newReceivedChallengeHtml = 
`
    <form class="kt-form pull-right" method="POST" action=" 
    {{action('ChallengeController@declineChallenge')}}">
    <input type="hidden" name="challengeid" value="`+data.gameid+` ">
    <button class="btn btn-label-danger btn-outline-danger btn-sm btn-upper btn-submit-declinechallenge"><i class="fa fa-trash-alt"></i> decline</button>
    </form> 
`;
receivedChallenges.html(newReceivedChallengeHtml + existingReceivedChallenges);
receivedChallengesWrapper.show(); 
}

Вот мой код AJAX для отправки формы:

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

$(".btn-submit-declinechallenge").click(function(e){
    e.preventDefault();

    let form = $(this).parent();
    let challengeid = jQuery('input[name="challengeid"]').val();

    $.ajax({
        type:'POST',
        url: form.attr('action'),
        data: form.serialize(),

    success:function(data){
        if(data.successful) {
            toastr.success(data.successful);
        }
        if(data.error) {
                toastr.error(data.error);
        }

        jQuery.each(data.errors, function(key, value){
            jQuery('#'+key+'-error-border-openchallenge').addClass('is-invalid')
            jQuery('#'+key+'-error-text-openchallenge').show();
            jQuery('#'+key+'-error-text-openchallenge').append('<p>'+value+'</p>');
        });
    }

    });
});

Если я отправляю форму после отображения ее через обновление страницы, она работает нормально. Если я пытаюсь отправить форму, как только она будет отображена через пушер, я получу 419.

Маркер CSRF находится в голове.

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

Я подозреваю, что это может быть связано с тем, что JS не может выбрать $ (this) .parent (); когда форма отображается через пушер без обновления страницы. Может быть, что-то делать с DOM, действительно не уверен. Любая помощь будет оценена.

ОБНОВЛЕНИЕ (ИСПРАВЛЕНО) Я изменил

$(".btn-submit-declinechallenge").click(function(e){e.preventDefault();

до

 $(document.body).on("click", ".btn-submit-declinechallenge", function(e){
                e.preventDefault();

Он работает как запланировано сейчас.

...