Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

NowAndHere's avatar

Ajax request -> server status 500 -> TokenMismatchException

I have two selects in the form, where options of the second one are dependant on value of first one (when user choose animal type in the first select, second one needs to be updated with appropriate list of breeds)

So here is the code:

  1. within the view:
$('select[name="animal_id"]').change(function() {
    var animal_id = $(this).val();
    $.ajaxSetup({
        headers: {
                'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
            }
    })
    $.ajax({ 
        type: 'post',
        url: '{{ route("dashboard::pets::getBreed") }}',
        data: animal_id,
        success: function(data) {
            alert('$data = ' + data);
        }       
    });
});
  1. routes.php
Route::group(['middleware' => ['web']], function () {
    /* Routes for admin dashboard */
    Route::group(['prefix' => 'dashboard', 'as' => 'dashboard::'], function() {
    (...)
    /* Manage pets */
        Route::group(['prefix' => 'pets', 'as' => 'pets::'], function() {
        (...)
        /* Ajax requests */
         Route::post('ajax/getbreed','PetsController@ajaxGetBreed')->name('getBreed');  // Route name: dashboard::pets::getBreed
        (...)
    });
    (...)
   });
});
  1. PetsController.php
/** Ajax requests **/
 public function ajaxGetBreed() {
        $data = 'it works!';
    return $data;
}

when value of first select (name='animal_id') is changed the effect (seen in console) is as follows:

"Failed to load resource: the server responded with a status of 500 (Internal Server Error) http://dogsandthecity.dev/dashboard/pets/ajax/getbreed" with extra info: "TokenMismatchException" that can be seen in "resources" tab of Safari's dev tool.

What am I doing wrong?

Thanks!

0 likes
9 replies
tylernathanreed's avatar

I always did it this way:

    $.ajax({ 
        type: 'post',
        url: '{{ route("dashboard::pets::getBreed") }}',
        data: {
        /* ... */
        _token: $('meta[name="_token"]').attr('content')
    },
        success: function(data) {
            alert('$data = ' + data);
        }       
    });
tykus's avatar

Are you sure that the meta tag in the header is called _token?

NowAndHere's avatar

but that works:

$('select[name="animal_id"]').change(function() {
            var animal_id = $(this).val();

            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('input[name="_token"]').attr('value')
                }
            })

            $.ajax({ 
                type: 'post',
                url: '{{route("dashboard::pets::getBreed")}}',
                data: animal_id,
                success: function(data) {
                    alert('$data = ' + data);
                }
            });
                
        });
tykus's avatar
tykus
Best Answer
Level 104

If you want to put the CSRF token in the meta tag, make sure you put the following within the <head> tags (in your layout template):

<meta name="_token" content="{!! csrf_token() !!}" />

You might have missed this in the tutorial because the meta tag was included at the bottom along with the scripts!

Good luck!

NowAndHere's avatar

yes, you're right, I have missed this, haven't realized that in the linked tutorial's code CSRF token is not placed within the form as I expected therefore code I copied could not have worked. Is there any advantage of providing CSRF token as meta tag against placing it as hidden input within a form? If not I will stick to amended code above.

tykus's avatar

Either is fine I suppose. I find a meta tag in the layout is useful if I am making a lot of AJAX requests because it is always in the same place and accessible to my JS

Please or to participate in this conversation.