dongyihao1099 2015-09-23 11:47
浏览 266
已采纳

Laravel csrf令牌与ajax POST请求不匹配

I am trying to delete data from database via ajax.

HTML:

@foreach($a as $lis)
  //some code
  <a href="#" class="delteadd" id="{{$lis['id']}}">Delete</a>
  //click action perform on this link                  
@endforeach

My ajax code:

$('body').on('click', '.delteadd', function (e) {
e.preventDefault();
//alert('am i here');
if (confirm('Are you sure you want to Delete Ad ?')) {
    var id = $(this).attr('id');
    $.ajax({
        method: "POST",
        url: "{{url()}}/delteadd",
        }).done(function( msg ) {
        if(msg.error == 0){
            //$('.sucess-status-update').html(msg.message);
            alert(msg.message);
        }else{
            alert(msg.message);
            //$('.error-favourite-message').html(msg.message);
        }
    });
} else {
    return false;
}
});

This is my query to fetch data from database...

$a = Test::with('hitsCount')->where('userid', $id)->get()->toArray();

But when i click on Delete link data not deleted and show csrf_token mismatch...

  • 写回答

11条回答 默认 最新

  • dsxcv5652 2015-09-23 11:54
    关注

    You have to add data in your ajax request. I hope so it will be work.

    data: {
            "_token": "{{ csrf_token() }}",
            "id": id
            }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • doxqszx09742 2016-06-02 03:19
    关注

    I think is better put the token in the form, and get this token by id

    <input type="hidden" name="_token" id="token" value="{{ csrf_token() }}">
    

    And the JQUery :

    var data = {
            "_token": $('#token').val()
        };
    

    this way, your JS don't need to be in your blade files.

    评论
  • doudou20080720 2016-09-16 11:44
    关注

    I just added headers: in ajax call:

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

    in view:

    <div id = 'msg'>
         This message will be replaced using Ajax. Click the button to replace the message.
    </div>
    
    {{ Form::submit('Change', array('id' => 'ajax')) }}
    

    ajax function:

    <script>
     $(document).ready(function() {
        $(document).on('click', '#ajax', function () {
          $.ajax({
             type:'POST',
             url:'/ajax',
             headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
             success:function(data){
                $("#msg").html(data.msg);
             }
          });
        });
    });
    </script>
    

    in controller:

    public function call(){
        $msg = "This is a simple message.";
        return response()->json(array('msg'=> $msg), 200);
    }
    

    in routes.php

    Route::post('ajax', 'AjaxController@call');
    
    评论
  • doufan6033 2017-01-03 00:58
    关注

    I actually had this error and could not find a solution. I actually ended up not doing an ajax request. I don't know if this issue was due to this being sub domain on my server or what. Here's my jquery.

                $('#deleteMeal').click(function(event) {
                    var theId = $(event.currentTarget).attr("data-mealId");
                      $(function() {
                        $( "#filler" ).dialog({
                          resizable: false,
                          height:140,
                          modal: true,
                          buttons: {
                          "Are you sure you want to delete this Meal? Doing so will also delete this meal from other users Saved Meals.": function() {
                               $('#deleteMealLink').click();
    //                         jQuery.ajax({
    //                              url : 'http://www.mealog.com/mealtrist/meals/delete/' + theId,
    //                              type : 'POST',
    //                              success : function( response ) {
    //                                  $("#container").replaceWith("<h1 style='color:red'>Your Meal Has Been Deleted</h1>");
    //                              }
    //                          });
                            // similar behavior as clicking on a link
                               window.location.href = 'http://www.mealog.com/mealtrist/meals/delete/' + theId;
                              $( this ).dialog( "close" );
                            },
                            Cancel: function() {
                              $( this ).dialog( "close" );
                            }
                          }
                        });
                      });
                    });
    

    So I actually set up an anchor to go to my API rather than doing a post request, which is what I figure most applications do.

      <p><a href="http://<?php echo $domain; ?>/mealtrist/meals/delete/{{ $meal->id }}" id="deleteMealLink" data-mealId="{{$meal->id}}" ></a></p>
    
    评论
  • donglu1472 2017-01-26 06:19
    关注

    The best way to solve this problem "X-CSRF-TOKEN" is to add the following code to your main layout, and continue making your ajax calls normally:

    In header

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

    In script

    <script type="text/javascript">
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });
    </script>
    
    评论
  • dslf46995 2017-05-24 14:32
    关注

    If you are using template files, than you can put your meta tag in the head section (or whatever you name it) which contain your meta tags.

    @section('head')
    <meta name="csrf_token" content="{{ csrf_token() }}" />
    @endsection
    

    Next thing, you need to put the headers attribute to your ajax(in my example, I am using datatable with server-side processing:

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

    Here is the full datatable ajax example:

    $('#datatable_users').DataTable({
            "responsive": true,
            "serverSide": true,
            "processing": true,
            "paging": true,
            "searching": { "regex": true },
            "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
            "pageLength": 10,
            "ajax": {
                "type": "POST",
                "headers": {'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')},
                "url": "/getUsers",
                "dataType": "json",
                "contentType": 'application/json; charset=utf-8',
                "data": function (data) {
                    console.log(data);
                },
                "complete": function(response) {
                    console.log(response);
               }
            }
        });
    

    After doing this, you should get 200 status for your ajax request.

    评论
  • dongsechuan0535 2017-08-06 15:23
    关注

    if you are using jQuery to send AJAX Posts, add this code to all views:

    $( document ).on( 'ajaxSend', addLaravelCSRF );
    
    function addLaravelCSRF( event, jqxhr, settings ) {
        jqxhr.setRequestHeader( 'X-XSRF-TOKEN', getCookie( 'XSRF-TOKEN' ) );
    }
    
    function getCookie(name) {
        function escape(s) { return s.replace(/([.*+?\^${}()|\[\]\/\\])/g, '\\$1'); };
        var match = document.cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
        return match ? match[1] : null;
    }
    

    Laravel adds a XSRF cookie to all requests, and we automatically append it to all AJAX requests just before submit.

    You may replace getCookie function if there is another function or jQuery plugin to do the same thing.

    评论
  • donglinxi1467 2017-11-10 03:10
    关注

    You should include a hidden CSRF (cross site request forgery) token field in the form so that the CSRF protection middleware can validate the request.

    Laravel automatically generates a CSRF "token" for each active user session managed by the application. This token is used to verify that the authenticated user is the one actually makin gthe requests to the application.

    So when doing ajax requests, you'll need to pass the csrf token via data parameter. Here's the sample code.

    var request = $.ajax({
        url : "http://localhost/some/action",
        method:"post",
        data : {"_token":"{{ csrf_token() }}"}  //pass the CSRF_TOKEN()
      });
    
    评论
  • dongpanshi2839 2018-11-19 07:01
    关注

    Know that there is an X-XSRF-TOKEN cookie that is set for convenience. Framework like Angular and others set it by default. Check this in the doc https://laravel.com/docs/5.7/csrf#csrf-x-xsrf-token You may like to use it.

    The best way is to use the meta, case the cookies are deactivated.

        var xsrfToken = decodeURIComponent(readCookie('XSRF-TOKEN'));
        if (xsrfToken) {
            $.ajaxSetup({
                headers: {
                    'X-XSRF-TOKEN': xsrfToken
                }
            });
        } else console.error('....');
    

    Here the recommended meta way (you can put the field any way, but meta is quiet nice):

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

    Note the use of decodeURIComponent(), it's decode from uri format which is used to store the cookie. [otherwise you will get an invalid payload exception in laravel].

    Here the section about the csrf cookie in the doc to check : https://laravel.com/docs/5.7/csrf#csrf-x-csrf-token

    Also here how laravel (bootstrap.js) is setting it for axios by default:

    let token = document.head.querySelector('meta[name="csrf-token"]');
    
    if (token) {
        window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
    } else {
        console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
    } 
    

    you can go check resources/js/bootstrap.js.

    And here read cookie function:

       function readCookie(name) {
            var nameEQ = name + "=";
            var ca = document.cookie.split(';');
            for (var i = 0; i < ca.length; i++) {
                var c = ca[i];
                while (c.charAt(0) == ' ') c = c.substring(1, c.length);
                if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
           }
            return null;
        }
    
    评论
  • douruobokui58233 2019-07-16 05:42
    关注

    For Laravel 5.8, setting the csrf meta tag for your layout and setting the request header for csrf in ajax settings won't work if you are using ajax to submit a form that already includes a _token input field generated by the Laravel blade templating engine.

    You must include the already generated csrf token from the form with your ajax request because the server would be expecting it and not the one in your meta tag.

    For instance, this is how the _token input field generated by Blade looks like:

    <form>
        <input name="_token" type="hidden" value="cf54ty6y7yuuyyygytfggfd56667DfrSH8i">
        <input name="my_data" type="text" value="">
        <!-- other input fields -->
    </form>
    

    You then submit your form with ajax like this:

    <script> 
        $(document).ready(function() { 
            let token = $('form').find('input[name="_token"]').val();
            let myData = $('form').find('input[name="my_data"]').val();
            $('form').submit(function() { 
                $.ajax({ 
                    type:'POST', 
                    url:'/ajax', 
                    data: {_token: token, my_data: myData}
                    // headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}, // unnecessary 
                    // other ajax settings
                }); 
                return false;
            }); 
        }); 
    </script>
    

    The csrf token in the meta header is only useful when you are submitting a form without a Blade generated _token input field.

    评论
  • duanmo5724 2019-08-22 22:50
    关注

    Add an id to the meta element that holds the token

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

    And then you can get it in your Javascript

    $.ajax({
      url : "your_url",
      method:"post",
      data : {
        "_token": $('#csrf-token')[0].content  //pass the CSRF_TOKEN()
      },  
      ...
    });
    
    评论
查看更多回答(10条)

报告相同问题?

悬赏问题

  • ¥15 Java中import为灰色
  • ¥15 手机等其他智能设备被监听
  • ¥15 在win10 64位的vs打包MSI文件,放到win7 64位上安装成可执行exe文件后,点击程序不运行。
  • ¥50 大众点评用户浏览/消费记录爬虫
  • ¥15 求制作一个个人网页,
  • ¥15 寻涂色内存脚本作者有项目有市场有资源.却技术
  • ¥15 蓝桥杯c51单片机问题
  • ¥15 ajax跨域问题请求修改代码
  • ¥15 python matplotlib
  • ¥15 短信测压+语音,有偿,必须用Python