Chamada 419 do Laravel 5.5 ajax (status desconhecido)

145

Eu faço uma chamada ajax, mas continuo recebendo este erro:

419 (status desconhecido)

Não faço ideia do que está causando isso, vi em outras postagens que tem a ver com o token csrf, mas não tenho forma, então não sei como consertar isso.

minha ligação:

$('.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);
          }
     });
  });

Minha rota:

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

Meu método de controle

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

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

O objetivo final é exibir algo da resposta em um elemento html.

Chris
fonte
4
você teve isso? <meta name="csrf-token" content="{{ csrf_token() }}">
Hanlin Wang
@HanlinWang Não, eu não tenho um formulário, é apenas uma lista suspensa.
Chris
você adicionou {{csrf_field()}}no seu formulário?
Mr. Pyramid
3
suspensa é uma parte da forma que você precisa para fazer esse pedido através do formulário
Mr. Pyramid
1
ou passe o csrf_token em seus dados como este #{'_token': {{csrf_token()}}}
Mr. Pyramid

Respostas:

301

Use isso na seção principal:

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

e obtenha o token csrf no ajax:

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

Consulte a documentação do Laravel csrf_token

Kannan K
fonte
1
Obrigado, funcionou para mim. Eu estava tentando usar o método 'DELETE' para a chamada ajax e isso funcionou como um encanto.
Salvo
4
Eu tenho esse código exato configurado, mas ainda estou enfrentando o problema do OP na seguinte situação: o usuário está conectado, mas o site permanece inativo por um longo período (por exemplo, o computador entra no modo de suspensão com o navegador aberto). Nesse caso, quando o usuário volta ao computador e tenta uma chamada AJAX, esse erro ocorre. Após uma recarga, tudo volta ao normal. Alguém tem uma solução para isto?
jovan
@jovan Existem duas maneiras de conseguir isso facilmente. Dê uma olhada nessas incríveis bibliotecas jquery https://www.jqueryscript.net/other/Session-Timeout-Alert-Plugin-With-jQuery-userTimeout.html https://github.com/kidh0/jquery.idle . Em segundo lugar, na sua solicitação ajax, verifique se ele retorna um código de erro 419 e depois redirecione.
riliwanrabo
@ jovan Eu também estava lutando com isso e até mesmo fechando o navegador, etc. não resolveria o problema. No entanto, consegui descobrir como corrigi-lo e colocando a linha de código 'ajaxsetup ()' mencionada acima DENTRO da minha chamada post () - o token csrf foi configurado corretamente e tudo começou a funcionar perfeitamente.
SupaMonkey
2
Mas porque 419 Unknown status? Por que não 419 Invalid CSRF tokenou alguma resposta útil existente? De onde isso vem? Por quê? Etc
Rudie
26

Outra maneira de resolver isso é usar o _tokencampo em dados ajax e definir o valor {{csrf_token()}}em blade. Aqui está um código que eu tentei no meu final.

$.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
fonte
cabeçalhos: {'X-CSRF-TOKEN': $ ('meta [name = "csrf-token"]'). attr ('content')},
Kamlesh 19/04/19
12

Isso é semelhante à resposta de Kannan. No entanto, isso corrige um problema em que o token não deveria ser enviado para sites entre domínios. Isso definirá o cabeçalho apenas se for uma solicitação local.

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
fonte
A configuração normal do cabeçalho funcionou para mim por um tempo, mas começou aleatoriamente a ter problemas após meses de bom funcionamento. Não sei ao certo por que começou a ter problemas do nada, mas essa solução funcionou muito bem e resolveu o problema para mim.
Frank A.
7

use isso na sua página

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

e no seu ajax usou nos dados:

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

isso é:

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

Obrigado.

Y. Joy Ch. Singha
fonte
7

É possível que o domínio da sessão não corresponda ao URL do seu aplicativo e / ou ao host usado para acessar o aplicativo.

1.) Verifique o seu arquivo .env:

SESSION_DOMAIN=example.com
APP_URL=example.com

2.) Verifique config / session.php

Verifique os valores para garantir que eles estejam corretos.

Jeff Callahan
fonte
1
Esta foi a solução correta para mim. Muito frustrante, o código HTTP 419 não corresponde à especificação HTTP e pode significar muitas coisas.
quer
5

Se você já fez as sugestões acima e ainda está com o problema.

Certifique-se de que a variável env:

SESSION_SECURE_COOKIE

Está definido como false se você não tiver um certificado SSL, como no local.

2Fwebd
fonte
4

no meu caso, esqueci de adicionar a entrada csrf_token ao formulário enviado. então eu fiz esse 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
fonte
1
este <input type="hidden" id="_token" value="{{ csrf_token() }}">é necesary mesmo se fizermos um submeter ajax whitouth, caso contrário, eu tenho um estranho 419 erro
Sr.PEDRO
3

Mesmo que você tenha uma csrf_token, se você autentica suas ações do controlador usando o Laravel, Policiestambém pode ter uma resposta 419. Nesse caso, você deve adicionar as funções de política necessárias em sua Policyclasse.

Tharanga
fonte
3

Se você estiver carregando .js de um arquivo, precisará definir uma variável com o csrf_token no arquivo "principal" .blade.php em que está importando o .js e usar a variável na sua chamada 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
fonte
1

alguns 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>
...
PORQUE
fonte
1

apenas serialize os dados do formulário e resolva o problema.

data: $('#form_id').serialize(),
Muhammad Umair
fonte
1

Você precisa obter o token csrf ..

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

Depois de fazer o mesmo problema, basta adicionar esta metatag< meta name="csrf-token" content="{{ csrf_token() }}" >

Depois disso, também ocorre o erro, você pode verificar o erro do Ajax. Em seguida, verifique também o erro do 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
fonte
1
formData = new FormData();
formData.append('_token', "{{csrf_token()}}");
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
learnkevin
fonte
Obrigado por este trecho de código, que pode fornecer ajuda imediata e limitada. Uma explicação adequada melhoraria bastante seu valor a longo prazo, mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras perguntas semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
CertainPerformance
1

Atualização do Laravel 2019, Nunca pensei que fosse postar isso, mas para desenvolvedores como eu, usando o navegador buscar a API no Laravel 5.8 e superior. Você precisa passar seu token pelo parâmetro 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
fonte
1

Eu havia SESSION_SECURE_COOKIEdefinido como true para que meu ambiente de desenvolvimento não funcionasse durante o login, portanto, adicionei SESSION_SECURE_COOKIE=false ao meu arquivo .env dev e tudo funciona bem. Meu erro foi alterar o arquivo session.php em vez de adicionar a variável ao arquivo .env.

Dunks1980
fonte
0

Esse erro também ocorre se você esquecer de incluir isso, em sua solicitação de envio de ajax (POST), contentType: false, processData: false,

Shamseer Ahammed
fonte
0

Recebi esse erro, embora eu já estivesse enviando token csrf. Acabou que não havia mais espaço no servidor.

NicholasTes
fonte
0

Isso funciona muito bem nos casos em que você não precisa de um formulário.

use isso no cabeçalho:

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

e isso no seu código JavaScript:

$.ajaxSetup({
        headers: {
        'X-CSRF-TOKEN': '<?php echo csrf_token() ?>'
        }
    });
lomelisan
fonte
0

Uma maneira simples de corrigir um status 419 desconhecido no seu console é colocar esse script dentro do seu FORMULÁRIO. {{csrf_field ()}}

Denz A Gatcho
fonte
0

Isso funcionou para mim:

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

Após este conjunto, faça uma chamada AJAX regular. Exemplo:

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

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

       success:function(response){

          // Log response
          console.log(response);

       }

    });
Nole
fonte