लारवेल सीएसआरएफ टोकन अजाक्स पोस्ट अनुरोध के लिए बेमेल


114

मैं ajax के माध्यम से डेटाबेस से डेटा को हटाने की कोशिश कर रहा हूं।

HTML:

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

मेरा अजाक्स कोड:

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

यह डेटाबेस से डेटा लाने के लिए मेरी क्वेरी है ...

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

लेकिन जब मैं डिलीट लिंक डेटा पर क्लिक करता हूं डिलीट नहीं होता है और csrf_token मिसमैच दिखाता है ...



आपको अपने अजाक्स कोड में सफलता और त्रुटि को जोड़ना चाहिए। त्रुटि समस्या दिखाएगी। stackoverflow.com/questions/45668337/…
reza jafari

जवाबों:


176

आपको अपने ajax अनुरोध में डेटा जोड़ना होगा। मुझे उम्मीद है कि यह काम होगा।

data: {
        "_token": "{{ csrf_token() }}",
        "id": id
        }

32
अगर अजाक्स फ़ंक्शन .jsफ़ाइल में स्थित है तो क्या होगा ?
ब्रैन

1
यह Laravel 5.7 पर काम नहीं करता है। zarpio का जवाब सही है।
उमर मर्सिया

1
समारोह में एक परम के रूप में टोकन भेजने @Brane
Abdelalim Hassouna

यह Laravel 5.8 में काम नहीं करता है। यह अभी भी टोकन बेमेल कहता है। एक सरल समाधान के लिए नीचे मेरे उत्तर की जाँच करें
Gjaa

एक json अनुरोध के बाद लार्वा को csrf टोकन बदल देता है? क्या आपको नए को मुख्य पृष्ठ पर भेजने की आवश्यकता है?
डेवफ्रैसोनी

185

इस समस्या को हल करने का सबसे अच्छा तरीका "X-CSRF-TOKEN" है, जो आपके मुख्य लेआउट में निम्नलिखित कोड जोड़ सकता है, और अपने ajax कॉल को सामान्य रूप से जारी रखता है:

हेडर में

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

स्क्रिप्ट में

<script type="text/javascript">
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});
</script>

5
धन्यवाद दोस्त। यह एक और अधिक अच्छी तरह से गोल समाधान है! इस तरह से आप बस इसे एक बार सेट अप करें और उसके बाद बस अपना सामान्य $ .ajax कोड लिखने के बारे में जाने।
pkid169

4
यह बेहतर उपाय है क्योंकि आप इसे .jsफ़ाइलों के अंदर उपयोग कर सकते हैं
एडम

3
अब तक का सबसे अच्छा जवाब। धन्यवाद।
पॉल डेनिसीविच

क्या होगा अगर "वैश्विक: गलत"?
मिशेल

1
प्रत्येक कॉल के बाद csrf को कैसे अपडेट किया जा सकता है? पहला कॉल महान काम करता है, CSRF टोकन के कारण उप-कॉल विफल हो जाती है।
Jjsg08

28

मुझे लगता है कि फॉर्म में टोकन डालना बेहतर है, और आईडी द्वारा इस टोकन को प्राप्त करें

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

और जेकरी:

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

इस तरह, आपके JS को आपकी ब्लेड फ़ाइलों में होने की आवश्यकता नहीं है।


25

मैंने अभी headers:अजाक्स कॉल में जोड़ा :

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

दृश्य में:

<div id = 'msg'>
     This message will be replaced using Ajax. Click the button to replace the message.
</div>

{{ Form::submit('Change', array('id' => 'ajax')) }}

अजाक्स समारोह:

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

नियंत्रक में:

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

मार्गों में

Route::post('ajax', 'AjaxController@call');

1
अजाक्स कॉल में हेडर जोड़ने से मुझे मदद मिली।
चौधरी वकास

1
यह सबसे अच्छा उत्तर है क्योंकि इसमें ब्लेड फाइल में जावास्क्रिप्ट की आवश्यकता नहीं होती है (जब तक कि आप इसे ब्लेड फाइल में नहीं चाहते हैं, लेकिन तब इसे हर बार किसी को उस पेज पर आने के लिए प्रदान किया जा रहा है)
Zachary Weixelbaum

11

यदि आप टेम्पलेट फ़ाइलों का उपयोग कर रहे हैं, तो आप अपने metaटैग को सिर में रख सकते हैं section(या जो भी आप इसे नाम देते हैं) जिसमें आपके metaटैग शामिल हैं ।

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

अगली बात, आपको headersअपनी विशेषता रखने की जरूरत है ajax(मेरे उदाहरण में, मैं datatableसर्वर-साइड प्रोसेसिंग के साथ उपयोग कर रहा हूं :

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

यहाँ पूर्ण datatableAJAX उदाहरण है:

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

ऐसा करने के बाद, आपको 200 statusअपने ajaxअनुरोध के लिए मिलना चाहिए ।


6

पता है कि एक X-XSRF-TOKEN कुकी है जो सुविधा के लिए निर्धारित है। एंगुलर जैसे फ्रेमवर्क और अन्य इसे डिफ़ॉल्ट रूप से सेट करते हैं। डॉक् https://laravel.com/docs/5.7/csrf#csrf-x-xsrf-token में इसे जांचें आप इसका उपयोग करना पसंद कर सकते हैं।

सबसे अच्छा तरीका है कि मेटा का उपयोग किया जाए, कुकीज़ को निष्क्रिय कर दिया जाए।

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

यहां अनुशंसित मेटा तरीका (आप फ़ील्ड को किसी भी तरह से रख सकते हैं, लेकिन मेटा शांत अच्छा है):

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

के उपयोग पर ध्यान दें decodeURIComponent(), यह uri प्रारूप से डिकोड होता है जिसका उपयोग कुकी को संग्रहीत करने के लिए किया जाता है। [अन्यथा आपको लारवेल में एक अवैध पेलोड अपवाद मिलेगा]।

यहां डॉर्क में csrf कुकी के बारे में जांच करने के लिए अनुभाग: https://laravel.com/docs/5.7/csrf#csrf-x-csrf-token

यहां भी बताया गया है कि कैसे लार्वेल (बूटस्ट्रैप.जेएस) इसे डिफ़ॉल्ट रूप से अक्षीयता के लिए स्थापित कर रहा है:

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

आप जाँच कर सकते हैं resources/js/bootstrap.js

और यहाँ कुकी फ़ंक्शन पढ़ें:

   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;
    }

5

टोकन idरखने वाले metaतत्व में जोड़ें

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

और फिर आप इसे अपने जावास्क्रिप्ट में प्राप्त कर सकते हैं

$.ajax({
  url : "your_url",
  method:"post",
  data : {
    "_token": $('#csrf-token')[0].content  //pass the CSRF_TOKEN()
  },  
  ...
});

1
यदि आप एक आईडी नहीं जोड़ना चाहते हैं, तो इसके बजाय: $ ("[name = csrf-token]") का उपयोग करें। attr ("सामग्री")। यह नाम गुण द्वारा सही तत्व लाएगा।
पेड्रो सोसा

3

यदि आप AJAX पोस्ट भेजने के लिए jQuery का उपयोग कर रहे हैं, तो सभी विचारों में यह कोड जोड़ें:

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

लारवेल सभी अनुरोधों के लिए एक एक्सएसआरएफ कुकी जोड़ता है, और हम इसे सबमिट करने से पहले स्वचालित रूप से सभी AJAX अनुरोधों के लिए जोड़ते हैं।

यदि समान कार्य करने के लिए कोई अन्य फ़ंक्शन या jQuery प्लगइन है, तो आप getCookie फ़ंक्शन को प्रतिस्थापित कर सकते हैं।


1

Laravel 5.8 के लिए, अपने लेआउट के लिए csrf मेटा टैग सेट करना और csrf के लिए ajax सेटिंग्स में अनुरोध शीर्षलेख सेट करने से काम नहीं चलेगा यदि आप ajax का उपयोग किसी फॉर्म को जमा करने के लिए कर रहे हैं जिसमें पहले से ही एक शामिल है _token Laravel templating इंजन द्वारा उत्पन्न इनपुट फ़ील्ड ।

आपको अपने ajax रिक्वेस्ट के साथ फॉर्म में पहले से जेनरेट किए गए csrf टोकन को शामिल करना होगा क्योंकि सर्वर यह अपेक्षा कर रहा होगा न कि आपके मेटा टैग में।

उदाहरण के लिए, इस _tokenतरह ब्लेड द्वारा उत्पन्न इनपुट क्षेत्र दिखता है:

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

आप फिर अपना फॉर्म इस तरह से अजाक्स के साथ जमा करें:

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

मेटा हेडर में सीएसआरएफ टोकन केवल तब उपयोगी होता है जब आप ब्लेड जनित _tokenइनपुट फील्ड के बिना फॉर्म सबमिट कर रहे होते हैं ।


1

जो कभी भी स्वीकार किए गए उत्तर @Deepak saini के साथ समस्या हो रही है, को दूर करने का प्रयास करें

cache:false,
processData:false,
contentType:false,

अजाक्स कॉल के लिए।

उपयोग

dataType:"json",

0

मेरे पास वास्तव में यह त्रुटि थी और इसका समाधान नहीं मिल सका। मैं वास्तव में एक ajax अनुरोध नहीं कर रहा था। मुझे नहीं पता कि यह समस्या मेरे सर्वर पर उप डोमेन होने के कारण थी या क्या। यहाँ मेरा 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" );
                        }
                      }
                    });
                  });
                });

इसलिए मैंने वास्तव में एक पोस्ट रिक्वेस्ट करने के बजाय अपने API पर जाने के लिए एक एंकर की स्थापना की, जो कि मुझे लगता है कि मैं सबसे ज्यादा आवेदन करता हूं।

  <p><a href="http://<?php echo $domain; ?>/mealtrist/meals/delete/{{ $meal->id }}" id="deleteMealLink" data-mealId="{{$meal->id}}" ></a></p>

0

आपको प्रपत्र में एक छिपा हुआ CSRF (क्रॉस साइट अनुरोध जालसाजी) टोकन फ़ील्ड शामिल करना चाहिए ताकि CSRF सुरक्षा मिडलवेयर अनुरोध को मान्य कर सके।

लारवेल स्वचालित रूप से एप्लिकेशन द्वारा प्रबंधित प्रत्येक सक्रिय उपयोगकर्ता सत्र के लिए एक सीएसआरएफ "टोकन" उत्पन्न करता है। इस टोकन का उपयोग यह सत्यापित करने के लिए किया जाता है कि प्रमाणित उपयोगकर्ता आवेदन के लिए वास्तव में makin gthe अनुरोध करता है।

अजाक्स अनुरोध करते समय, आपको डेटा पैरामीटर के माध्यम से सीएसआरएफ टोकन पास करना होगा । यहाँ नमूना कोड है।

var request = $.ajax({
    url : "http://localhost/some/action",
    method:"post",
    data : {"_token":"{{ csrf_token() }}"}  //pass the CSRF_TOKEN()
  });

0

मैं सिर्फ फॉर्म और उसके काम करने के तरीके के अंदर @csrf का उपयोग करता हूं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.