Laravel 5.5 ajax call 419 (estado desconocido)

145

Hago una llamada ajax pero sigo recibiendo este error:

419 (estado desconocido)

No tengo idea de qué está causando esto. Vi en otras publicaciones que tiene que ver con token csrf, pero no tengo forma, así que no sé cómo solucionarlo.

mi llamada:

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

Mi ruta:

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

Mi método controlador

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

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

El objetivo final es mostrar algo de la respuesta en un elemento html.

Chris
fuente
44
tuviste esto? <meta name="csrf-token" content="{{ csrf_token() }}">
Hanlin Wang
@HanlinWang No, no tengo un formulario, es solo un menú desplegable.
Chris
has añadido {{csrf_field()}}en tu formulario ??
Sr. Pyramid
3
el menú desplegable es parte del formulario que necesita para hacer esa solicitud a través del formulario
Sr. Pyramid
1
o pase el csrf_token en sus datos de esta manera{'_token': {{csrf_token()}}}
Sr. Pyramid

Respuestas:

301

Use esto en la sección de la cabeza:

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

y obtenga el token csrf en ajax:

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

Consulte la documentación de Laravel csrf_token

Kannan K
fuente
1
Gracias, funcionó para mí. Estaba tratando de usar el método 'BORRAR' para la llamada ajax y esto funcionó de maravilla.
Salvo
44
Tengo este código exacto configurado, pero todavía estoy experimentando el problema de OP en la siguiente situación: el usuario ha iniciado sesión, pero el sitio permanece inactivo durante un largo período (por ejemplo, la computadora se queda inactiva con el navegador abierto). En este caso, cuando el usuario vuelve a la computadora e intenta una llamada AJAX, se produce este error. Después de una recarga, todo vuelve a la normalidad. Alguien tiene una solución para esto?
jovan
@jovan Hay dos formas de lograrlo fácilmente. Eche un vistazo a estas increíbles bibliotecas de jquery https://www.jqueryscript.net/other/Session-Timeout-Alert-Plugin-With-jQuery-userTimeout.html https://github.com/kidh0/jquery.idle . En segundo lugar, en su solicitud ajax, verifique si devuelve un código de error de 419 y luego redirija.
riliwanrabo
@jovan Yo también estaba luchando con esto e incluso cerrar el navegador, etc., no solucionaría el problema. Sin embargo, pude encontrar cómo solucionarlo y al poner la línea de código 'ajaxsetup ()' mencionada anteriormente DENTRO de mi llamada post (), el token csrf se configuró correctamente y todo comenzó a funcionar sin problemas.
SupaMonkey
2
Pero por que 419 Unknown status? ¿Por qué no 419 Invalid CSRF tokeno alguna respuesta útil existente? ¿De dónde viene? ¿Por qué? Etc.
Rudie
26

Otra forma de resolver esto es usar el _tokencampo en datos ajax y establecer el valor de {{csrf_token()}}en blade. Aquí hay un código de trabajo que acabo de probar al 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
fuente
encabezados: {'X-CSRF-TOKEN': $ ('meta [name = "csrf-token"]'). attr ('content')},
Kamlesh
12

Esto es similar a la respuesta de Kannan. Sin embargo, esto soluciona un problema donde el token no debe enviarse a sitios de dominio cruzado. Esto solo establecerá el encabezado si es una solicitud 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
fuente
La configuración normal del encabezado funcionó para mí por un tiempo, pero al azar comenzó a tener problemas después de meses de trabajar bien. No estoy completamente seguro de por qué comenzó a tener problemas de la nada, pero esta solución funcionó muy bien y me solucionó el problema.
Frank A.
7

usa esto en tu página

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

y en tu ajax lo usaste en datos:

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

es decir:

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

Gracias.

Y. Joy Ch. Singha
fuente
7

Es posible que su dominio de sesión no coincida con la URL de su aplicación y / o el host que se utiliza para acceder a la aplicación.

1.) Verifique su archivo .env:

SESSION_DOMAIN=example.com
APP_URL=example.com

2.) Verifique config / session.php

Verifique los valores para asegurarse de que sean correctos.

Jeff Callahan
fuente
1
Esta fue la solución correcta para mí. Muy frustrante, el código HTTP 419 no coincide con la especificación HTTP y puede significar muchas cosas.
Cobolt
5

Si ya hizo las sugerencias anteriores y aún tiene el problema.

Asegúrese de que la variable env:

SESSION_SECURE_COOKIE

Se establece en false si no tiene un certificado SSL, como en local.

2Fwebd
fuente
4

en mi caso, olvidé agregar la entrada csrf_token al formulario enviado. así que hice este 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
El hombre muerto
fuente
1
esto <input type="hidden" id="_token" value="{{ csrf_token() }}">es necesario incluso si hacemos un envío con ajax sur, de lo contrario recibí un extraño error 419
Sr.PEDRO
3

Aunque tenga un csrf_token, si está autenticando las acciones de su controlador usando Laravel, Policiestambién puede tener una respuesta 419. En ese caso, debe agregar las funciones de política necesarias en su Policyclase.

Tharanga
fuente
3

Si está cargando .js desde un archivo, debe establecer una variable con csrf_token en su archivo "main" .blade.php donde está importando .js y usar la variable en su llamada 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
fuente
1

algunas referencias =>

...
<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>
...
POR QUÉ
fuente
1

solo serialice los datos del formulario y resuelva su problema.

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

Tienes que obtener el token csrf.

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

Después de hacer el mismo problema, solo agrega esta metaetiqueta< meta name="csrf-token" content="{{ csrf_token() }}" >

Después de esto también surge el error, puede verificar el error de Ajax. Entonces también verifique el error 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
fuente
1
formData = new FormData();
formData.append('_token', "{{csrf_token()}}");
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
aprenderkevin
fuente
Gracias por este fragmento de código, que podría proporcionar una ayuda limitada e inmediata. Una explicación adecuada mejoraría enormemente su valor a largo plazo al mostrar por qué esta es una buena solución al problema y la haría más útil para futuros lectores con otras preguntas similares. Por favor, editar su respuesta a añadir un poco de explicación, incluyendo los supuestos realizados.
CertainPerformance el
1

Actualización de Laravel 2019, nunca pensé que publicaría esto, pero para aquellos desarrolladores como yo que utilizamos la API de búsqueda del navegador en Laravel 5.8 y superior. Tienes que pasar tu token a través del parámetro de encabezado.

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
fuente
1

Había SESSION_SECURE_COOKIEestablecido en true para que mi entorno de desarrollo no funcionara al iniciar sesión, así que agregué SESSION_SECURE_COOKIE=false a mi archivo de desarrollo .env y todo funciona bien, mi error fue cambiar el archivo session.php en lugar de agregar la variable al archivo .env.

Dunks1980
fuente
0

Este error también ocurre si olvidó incluir esto, en su solicitud de envío ajax (POST), contentType: false, processData: false,

Shamseer Ahammed
fuente
0

Recibí este error a pesar de que ya había estado enviando el token csrf. Resultó que no quedaba más espacio en el servidor.

NicholasTes
fuente
0

Esto funciona muy bien para aquellos casos en los que no necesita un formulario.

use esto en el encabezado:

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

y esto en tu código JavaScript:

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

Una forma simple de corregir un estado desconocido 419 en su consola es poner este script dentro de su FORM. {{csrf_field ()}}

Denz A Gatcho
fuente
0

Esto funcionó para mí:

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

Después de esto, establezca una llamada AJAX regular. Ejemplo:

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

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

       success:function(response){

          // Log response
          console.log(response);

       }

    });
Nole
fuente