Laravel 5.5 Ajax wywołanie 419 (nieznany stan)

145

Wykonuję wywołanie Ajax, ale wciąż otrzymuję ten błąd:

419 (stan nieznany)

Nie mam pojęcia, co to powoduje, widziałem w innych postach, że musi coś zrobić z tokenem csrf, ale nie mam formularza, więc nie wiem, jak to naprawić.

mój telefon:

$('.company-selector li > a').click(function(e) {
     e.preventDefault();

     var companyId = $(this).data("company-id");


      $.ajax({
          headers: {
          'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
          },
          url: '/fetch-company/' + companyId,
          dataType : 'json',
          type: 'POST',
          data: {},
          contentType: false,
          processData: false,
          success:function(response) {
               console.log(response);
          }
     });
  });

Moja trasa:

Route::post('fetch-company/{companyId}', 'HomeController@fetchCompany');

Moja metoda kontrolera

/**
 * Fetches a company
 *
 * @param $companyId
 *
 * @return array
 */
public function fetchCompany($companyId)
{
    $company = Company::where('id', $companyId)->first();

    return response()->json($company);
}

Ostatecznym celem jest wyświetlenie czegoś z odpowiedzi w elemencie html.

Chris
źródło
4
miałeś to <meta name="csrf-token" content="{{ csrf_token() }}">
Hanlin Wang
@HanlinWang Nie, nie mam formularza, to tylko lista rozwijana.
Chris,
czy dodałeś {{csrf_field()}}w swoim formularzu ??
Mr. Pyramid
3
lista rozwijana jest częścią formularza, którą należy złożyć za pośrednictwem formularza
Mr. Pyramid
1
lub podaj csrf_token w swoich danych w ten sposób{'_token': {{csrf_token()}}}
Mr. Pyramid

Odpowiedzi:

300

Użyj tego w sekcji głównej:

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

i pobierz token csrf w Ajax:

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

Proszę zapoznać się z dokumentacją Laravel csrf_token

Kannan K
źródło
1
Dzięki, u mnie zadziałało. Próbowałem użyć metody „DELETE” dla wywołania ajax i to działało jak urok.
Salvo,
4
Mam ustawiony dokładnie ten kod, ale nadal mam problem z OP w następującej sytuacji: użytkownik jest zalogowany, ale witryna pozostaje bezczynna przez długi czas (na przykład komputer przechodzi w stan uśpienia przy otwartej przeglądarce). W takim przypadku, gdy użytkownik wróci do komputera i spróbuje wywołać AJAX, wystąpi ten błąd. Po przeładowaniu wszystko wraca do normy. Czy ktoś ma na to rozwiązanie?
jovan
@jovan Są dwa sposoby na osiągnięcie tego w prosty sposób. Spójrz na te niesamowite biblioteki jquery https://www.jqueryscript.net/other/Session-Timeout-Alert-Plugin-With-jQuery-userTimeout.html https://github.com/kidh0/jquery.idle . Po drugie, na żądanie AJAX sprawdź, czy zwraca kod błędu 419, a następnie przekieruj.
riliwanrabo
@jovan Ja też zmagałem się z tym i nawet zamknięcie przeglądarki itp. nie rozwiązało problemu. Udało mi się jednak znaleźć jak to naprawić i wstawiając wspomnianą powyżej linię kodu „ajaxsetup ()” W RAMACH mojego wywołania post () - token csrf został ustawiony poprawnie i wszystko zaczęło działać bez zarzutu.
SupaMonkey
2
Ale dlaczego 419 Unknown status? Dlaczego nie 419 Invalid CSRF tokenlub jakaś istniejąca, użyteczna odpowiedź? Skąd to pochodzi? Czemu? Etc
Rudie,
26

Innym sposobem rozwiązania tego problemu jest użycie _tokenpola w danych Ajax i ustawienie wartości {{csrf_token()}}w module blade. Oto działający kod, który właśnie wypróbowałem na końcu.

$.ajax({
    type: "POST",
    url: '/your_url',
    data: { somefield: "Some field value", _token: '{{csrf_token()}}' },
    success: function (data) {
       console.log(data);
    },
    error: function (data, textStatus, errorThrown) {
        console.log(data);

    },
});
Waqas Bukhary
źródło
headers: {'X-CSRF-TOKEN': $ ('meta [name = "csrf-token"]'). attr ('content')},
Kamlesh
12

Jest to podobne do odpowiedzi Kannana. Jednak rozwiązuje to problem polegający na tym, że token nie powinien być wysyłany do witryn międzydomenowych. Spowoduje to ustawienie nagłówka tylko wtedy, gdy jest to żądanie lokalne.

HTML:

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

JS:

$.ajaxSetup({
    beforeSend: function(xhr, type) {
        if (!type.crossDomain) {
            xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
        }
    },
});
Damien Ó Ceallaigh
źródło
Normalna konfiguracja nagłówka działała przez jakiś czas, ale losowo zaczęła pojawiać się problemy po miesiącach dobrej pracy. Nie jestem do końca pewien, dlaczego zaczęły pojawiać się problemy znikąd, ale to rozwiązanie działało świetnie i rozwiązało problem.
Frank A.
7

użyj tego na swojej stronie

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

aw twoim Ajax użył go w danych:

_token: '{!! csrf_token() !!}',

to jest:

$.ajax({
          url: '/fetch-company/' + companyId,
          dataType : 'json',
          type: 'POST',
          data: {
                   _token: '{!! csrf_token() !!}',
                 },
          contentType: false,
          processData: false,
          success:function(response) {
               console.log(response);
          }
     });

Dzięki.

Y. Joy Ch. Singha
źródło
7

Możliwe, że domena sesji nie jest zgodna z adresem URL aplikacji i / lub hostem używanym do uzyskania dostępu do aplikacji.

1.) Sprawdź plik .env:

SESSION_DOMAIN=example.com
APP_URL=example.com

2.) Sprawdź config / session.php

Sprawdź wartości, aby upewnić się, że są poprawne.

Jeff Callahan
źródło
1
To było dla mnie właściwe rozwiązanie. Bardzo frustrujące jest to, że kod HTTP 419 nie pasuje do specyfikacji HTTP i może oznaczać wiele rzeczy.
Cobolt,
5

Jeśli wykonałeś już powyższe sugestie i nadal masz problem.

Upewnij się, że zmienna env:

SESSION_SECURE_COOKIE

Ustawia się, false jeśli nie masz certyfikatu SSL, na przykład lokalnego.

2Fwebd
źródło
4

w moim przypadku zapomniałem dodać dane wejściowe csrf_token do przesłanego formularza. więc zrobiłem ten HTML:

<form class="form-material" id="myform">
...
<input type="file" name="l_img" id="l_img">
<input type="hidden" id="_token" value="{{ csrf_token() }}">
..
</form>

JS:

//setting containers
        var _token = $('input#_token').val();
        var l_img = $('input#l_img').val();
        var formData = new FormData();
        formData.append("_token", _token);
        formData.append("l_img", $('#l_img')[0].files[0]);

        if(!l_img) {
            //do error if no image uploaded
            return false;
        }
        else
        {
            $.ajax({
                type: "POST",
                url: "/my_url",
                contentType: false,
                processData: false,
                dataType: "json",
                data : formData,
                beforeSend: function()
                {
                    //do before send
                },
                success: function(data)
                {
                    //do success
                },
                error: function(jqXhr, textStatus, errorThrown) //jqXHR, textStatus, errorThrown
                {
                    if( jqXhr.status === "422" ) {
                        //do error
                    } else {
                        //do error
                    }
                }
            });
        }
        return false; //not to post the form physically
The Dead Guy
źródło
1
to <input type="hidden" id="_token" value="{{ csrf_token() }}">jest necesary nawet jeśli robimy złożyć whitouth ajax, inaczej mam dziwny błąd 419
Sr.PEDRO
3

Nawet jeśli masz csrf_token, jeśli uwierzytelniasz akcje kontrolera za pomocą Laravel, Policiesmożesz również uzyskać odpowiedź 419. W takim przypadku powinieneś dodać niezbędne funkcje strategii do swojej Policyklasy.

Tharanga
źródło
3

Jeśli ładujesz .js z pliku, musisz ustawić zmienną z csrf_token w swoim "głównym" pliku .blade.php, w którym importujesz .js i użyć tej zmiennej w wywołaniu ajax.

index.blade.php

...
...
<script src="{{ asset('js/anotherfile.js') }}"></script>
<script type="text/javascript">
        var token = '{{ csrf_token() }}';
</script>

anotherfile.js

$.ajax({
    url: 'yourUrl',
    type: 'POST',
    data: {
        '_token': token
    },
    dataType: "json",
    beforeSend:function(){
        //do stuff
    },
    success: function(data) {
        //do stuff
    },
    error: function(data) {
        //do stuff
    },
    complete: function(){
        //do stuff
    }
});
Wolfernand
źródło
1

niektóre refs =>

...
<head>
    // CSRF for all ajax call
    <meta name="csrf-token" content="{{ csrf_token() }}" />
</head>
 ...
 ...
<script>
    // CSRF for all ajax call
    $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': jQuery('meta[name="csrf-token"]').attr('content') } });
</script>
...
CZEMU
źródło
1

po prostu serializuj dane formularza i rozwiąż swój problem.

data: $('#form_id').serialize(),
Muhammad Umair
źródło
1

Musisz zdobyć token CSRF.

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

Po zrobieniu tego samego problemu, po prostu dodaj ten metatag< meta name="csrf-token" content="{{ csrf_token() }}" >

Po tym również pojawia się błąd, możesz sprawdzić błąd Ajax. Następnie sprawdź również błąd Ajax

$.ajax({
    url: 'some_unknown_page.html',
    success: function (response) {
        $('#post').html(response.responseText);
    },
    error: function (jqXHR, exception) {
        var msg = '';
        if (jqXHR.status === 0) {
            msg = 'Not connect.\n Verify Network.';
        } else if (jqXHR.status == 404) {
            msg = 'Requested page not found. [404]';
        } else if (jqXHR.status == 500) {
            msg = 'Internal Server Error [500].';
        } else if (exception === 'parsererror') {
            msg = 'Requested JSON parse failed.';
        } else if (exception === 'timeout') {
            msg = 'Time out error.';
        } else if (exception === 'abort') {
            msg = 'Ajax request aborted.';
        } else {
            msg = 'Uncaught Error.\n' + jqXHR.responseText;
        }
        $('#post').html(msg);
    },
});
Balaji Rajendran
źródło
1
formData = new FormData();
formData.append('_token', "{{csrf_token()}}");
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
learnkevin
źródło
Dziękujemy za ten fragment kodu, który może zapewnić ograniczoną, natychmiastową pomoc. Właściwe wyjaśnienie byłoby znacznie poprawić swoją długoterminową wartość pokazując dlaczego jest to dobre rozwiązanie problemu i byłoby bardziej użyteczne dla czytelników przyszłości z innymi, podobnymi pytaniami. Proszę edytować swoją odpowiedź dodać kilka wyjaśnień, w tym założeń już wykonanych.
CertainPerformance
1

Aktualizacja Laravel 2019, Nigdy nie myślałem, że to opublikuję, ale dla tych programistów, takich jak ja, używających api do pobierania przeglądarki na Laravel 5.8 i nowszych. Musisz przekazać swój token za pomocą parametru headers.

var _token = "{{ csrf_token }}";
fetch("{{url('add/new/comment')}}", {
                method: 'POST',
                headers: {
                    'X-CSRF-TOKEN': _token,
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(name, email, message, article_id)
            }).then(r => {
                return r.json();
            }).then(results => {}).catch(err => console.log(err));
Delino
źródło
1

Miałem SESSION_SECURE_COOKIEustawione na true więc moje środowisko dev nie działa podczas logowania, więc dodałem SESSION_SECURE_COOKIE=false do pliku mojego dev .env i wszystkie działa dobrze mój błąd się zmienia plik session.php zamiast dodanie zmiennej do pliku .env.

Dunks1980
źródło
0

Ten błąd występuje również, jeśli zapomniałeś go uwzględnić w żądaniu przesłania AJAX (POST), contentType: false, processData: false,

Shamseer Ahammed
źródło
0

Pojawił się ten błąd, mimo że wysyłałem już token CSRF. Okazało się, że na serwerze nie ma już miejsca.

NicholasTes
źródło
0

Działa to świetnie w przypadkach, w których nie potrzebujesz formularza.

użyj tego w nagłówku:

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

a to w kodzie JavaScript:

$.ajaxSetup({
        headers: {
        'X-CSRF-TOKEN': '<?php echo csrf_token() ?>'
        }
    });
lomelisan
źródło
0

Prostym sposobem naprawienia nieznanego 419 statusu na konsoli jest umieszczenie tego skryptu w FORMULARZU. {{csrf_field ()}}

Denz A Gatcho
źródło
0

To zadziałało dla mnie:

$.ajaxSetup({
  headers: {
    'X-CSRF-TOKEN': "{{ csrf_token() }}"
  }
});

Po tym ustaw regularne połączenie AJAX. Przykład:

    $.ajax({
       type:'POST',
       url:'custom_url',

       data:{name: "some name", password: "pass", email: "[email protected]"},

       success:function(response){

          // Log response
          console.log(response);

       }

    });
Nole
źródło