Laravel 5.5 Ajax呼叫419(未知状态)


145

我进行了ajax调用,但始终出现此错误:

419(未知状态)

不知道是什么原因导致的,我在其他帖子上看到过,它必须使用csrf令牌来做某事,但是我没有表格,所以我不知道该如何解决。

我的电话:

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

我的路线:

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

我的控制器方法

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

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

最终目标是在html元素中显示响应中的内容。


4
你有这个吗?<meta name="csrf-token" content="{{ csrf_token() }}">
Hanlin Wang

@HanlinWang不,我没有表格,只是下拉列表。
克里斯(Chris

您是否添加 {{csrf_field()}}了表格?
Pyramid先生

3
下拉是表格的一部分,你需要通过形式作出这样的要求
金字塔先生

1
或像这样在您的数据中传递csrf_token{'_token': {{csrf_token()}}}
金字塔先生

Answers:


300

在头部使用此命令:

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

并在ajax中获取csrf令牌:

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

请参考Laravel文档csrf_token


1
谢谢,对我有用。我试图使用'DELETE'方法进行ajax调用,这就像一种魅力。
Salvo

4
我已经设置了准确的代码,但是在以下情况下我仍然遇到OP的问题:用户已登录,但是该站点长时间处于空闲状态(例如,计算机在打开浏览器的状态下进入睡眠状态)。在这种情况下,当用户返回计算机并尝试AJAX调用时,就会发生此错误。重新加载后,一切恢复正常。有人对此有解决方案吗?
jovan

@jovan有两种方法可以轻松实现这一目标。看看这些很棒的jquery库https://www.jqueryscript.net/other/Session-Timeout-Alert-Plugin-With-jQuery-userTimeout.html https://github.com/kidh0/jquery.idle。其次,在您的ajax请求上,检查它是否返回错误代码419,然后重定向。
riliwanrabo

@jovan我也为此付出了很多努力,甚至关闭了浏览器,等等也无法解决问题。不过,我设法找到了解决方法,并将上述代码“ ajaxsetup()”放入了post()调用中,从而将其正确放置-csrf令牌已正确设置,并且一切正常运行。
SupaMonkey

2
但是为什么419 Unknown status呢?为什么不这样做419 Invalid CSRF token或有些现有的,有用的回应呢?它从何而来?为什么?等等
鲁迪18'Dec

26

解决此问题的另一种方法是使用_tokenajax数据中的字段并设置{{csrf_token()}}in blade 的值。这是我最后尝试的工作代码。

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

    },
});

标头:{'X-CSRF-TOKEN':$('meta [name =“ csrf-token”]')。attr('content')},
Kamlesh,

12

这类似于坎南的答案。但是,这解决了不应将令牌发送到跨域站点的问题。如果是本地请求,则只会设置标头。

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'));
        }
    },
});

正常的标头设置为我工作了一段时间,但经过几个月的正常工作后,随机开始出现问题。我不完全确定为什么它开始出现问题,但是这种解决方案效果很好,并为我解决了问题。
Frank A.

7

在您的页面中使用它

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

并在您的ajax中将其用于数据中:

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

那是:

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

谢谢。


7

您的会话域可能与您的应用程序URL和/或用于访问该应用程序的主机不匹配。

1.)检查您的.env文件:

SESSION_DOMAIN=example.com
APP_URL=example.com

2.)检查config / session.php

验证值以确保它们正确。


1
这对我来说是正确的解决方案。非常令人沮丧的是,HTTP 419代码与HTTP规范不匹配,可能意味着很多事情。
Cobolt

5

如果您已经完成了上述建议,但仍然遇到问题。

确保env变量:

SESSION_SECURE_COOKIE

false 如果您没有本地本地的SSL证书,设置为。


4

在我的情况下,我忘记将csrf_token输入添加到提交的表单中。所以我做了这个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

1
<input type="hidden" id="_token" value="{{ csrf_token() }}">即使我们提交了一个whithuth ajax,这也是必要的,否则我会遇到一个奇怪的419错误
SED.PEDRO 18'May

3

即使您有一个csrf_token,如果您使用Laravel对控制器操作进行身份验证,Policies也可以得到419响应。在这种情况下,您应该在Policy类中添加必要的策略功能。


3

如果要从文件加载.js,则必须在要导入.js的“主” .blade.php文件中设置带有csrf_token的变量,并在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
    }
});

1

一些裁判=>

...
<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>
...


1

您必须获取csrf令牌。

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

做完同样的问题后,只需添加此元标记< meta name="csrf-token" content="{{ csrf_token() }}" >

此后也出现错误,您可以检查Ajax错误。然后还要检查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);
    },
});

1
formData = new FormData();
formData.append('_token', "{{csrf_token()}}");
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);

感谢您提供此代码段,它可能会提供一些有限的即时帮助。通过说明为什么这是一个很好的解决方案,正确的解释将大大提高其长期价值,并且对于其他存在类似问题的读者来说,它将更加有用。请编辑您的答案以添加一些解释,包括您所做的假设。
某些性能

1

2019 Laravel更新,从没想过我会发布这个,但对于像我这样的开发人员,使用Laravel 5.8及更高版本上的浏览器获取API。您必须通过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));

1

我已经 SESSION_SECURE_COOKIE设置为true,所以我的开发环境在登录时无法正常工作,所以我将其添加SESSION_SECURE_COOKIE=false 到我的dev .env文件中,并且一切正常,我的错误是更改了session.php文件,而不是将变量添加到.env文件中。


0

如果您忘记在ajax提交请求(POST)中将其包括在内,则contentContent:false,processData:false,



0

对于不需要表单的情况,这非常有用。

在标头中使用:

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

这在您的JavaScript代码中:

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

0

解决控制台上419个未知状态的一种简单方法是将此脚本放入FORM中。{{csrf_field()}}


0

这为我工作:

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

在此之后设置常规的AJAX调用。例:

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

       data:{name: "some name", password: "pass", email: "test@test.com"},

       success:function(response){

          // Log response
          console.log(response);

       }

    });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.