Laravel 5: Ajax Post 500 (Internal Server Error)

35,001

Solution 1

When you make a request via POST to a resource controller, it automatically calls store method:

Verb    Path        Action  Route Name
----------------------------------
POST    /articles   store   articles.store

So, you just need to change ajax url to:

$.ajax({
        type: "POST",
        url: 'http://localhost/laravel-5/public/articles',

When you need to send the session token, you can add a global meta-tag like this is you website:

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

Then, just add the token via ajax's headers:

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

If you are using Form::open() function (LaravelCollective) it adds a hidden input with the token as value with the name _token. So, you can remove the meta-tag and edit your ajax's headers like this:

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

Solution 2

That's what I got exception 'Illuminate\Session\TokenMismatchException' in C:\xampp\htdocs\laravel-5\vendor\laravel\framework\src\Illuminate\Foundation\Htt‌​p\Middleware\VerifyCsrfToken.php:53

You're hitting Laravel's CSRF protection.

http://laravel.com/docs/5.1/routing#csrf-protection

You need to pass the hidden _token field's value. This can be done automatically on all jQuery-initiated AJAX requests by doing this in your application's JS:

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

Or, you can manually fetch and pass the value of the _token hidden field in each of your AJAX calls.

Share:
35,001
Halnex
Author by

Halnex

Updated on December 06, 2020

Comments

  • Halnex
    Halnex over 3 years

    I'm trying to submit data to the database via ajax. The submit article page works fine without ajax. I've added console.log() just to see if anything is going through, but instead I'm getting this error:

    POST http://localhost/laravel-5/public/articles/create 500 (Internal Server Error)

    What's wrong with my code? Is it the javascript or the controller?

    EDIT: I'm getting this in laravel.log

    exception 'Illuminate\Session\TokenMismatchException' in C:\xampp\htdocs\laravel-5\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:53

    Route

    Route::resource('articles', 'ArticlesController');
    

    Controller

    public function store(Requests\ArticleRequest $request)
        {
    
            $article = new Article($request->all());
            Auth::user()->articles()->save($article);
    
            $response = array(
                'status' => 'success',
                'msg' => 'Article has been posted.',
            );
            return \Response::json($response);
        }
    

    jQuery

    $(document).ready(function() {
        $('#frm').on('submit', function (e) {
            e.preventDefault();
            var title = $('#title').val();
            var body = $('#body').val();
            var published_at = $('#published_at').val();
            $.ajax({
                type: "POST",
                url: 'http://localhost/laravel-5/public/articles/create',
                dataType: 'JSON',
                data: {title: title, body: body, published_at: published_at},
                success: function( data ) {
                    $("#ajaxResponse").append(data.msg);
                    console.log(data);
                }
            });
        });
    

    View

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    
    <h1>Write a New Article</h1>
    
    <hr>
    
    {!! Form::open(['url' => 'articles', 'id' => 'frm']) !!}
        <p>
            {!! Form::label('title', 'Title:') !!}
            {!! Form::text('title') !!}
        </p>
    
        <p>
            {!! Form::label('body', 'Body:') !!}
            {!! Form::textarea('body') !!}
        </p>
    
        <p>
            {!! Form::label('published_at', 'Date:') !!}
            {!! Form::input('date', 'published_at', date('Y-m-d'), ['class' => 'form-control']) !!}
        </p>
    
        <p>
            {!! Form::submit('Submit Article', ['id' => 'submit']) !!}
        </p>
    {!! Form::close() !!}
    
    <h3 id="ajaxResponse"></h3>
    
    @if($errors->any())
        <ul>
        @foreach($errors->all() as $error)
            <li>{{ $error }}</li>
        @endforeach
        </ul>
    @endif
    
    <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
    <script src="{{ URL::asset('assets/js/ArticleCreate.js') }}"></script>
    

    });

  • Halnex
    Halnex over 8 years
    I am still getting the same error. I just check laravel logs and I'm getting this error exception 'Illuminate\Session\TokenMismatchException' in C:\xampp\htdocs\laravel-5\vendor\laravel\framework\src\Illum‌​inate\Foundation\Htt‌​p\Middleware\VerifyC‌​srfToken.php:53
  • manix
    manix over 8 years
    Thank you for downvote without a constructive comment about it :)
  • Halnex
    Halnex over 8 years
    I didn't downvote you. Infact, I just upvoted you because your solution works and the other guys didn't mention I need the meta tag in my view. But both of you are correct.
  • Halnex
    Halnex over 8 years
    Thank you, but I still need to answer a meta tag in my view. That sorted it all out.
  • manix
    manix over 8 years
    The problem is not the downvote, it is when people doesn't say anything xD. But that's cool, glad to help you!
  • Halnex
    Halnex over 8 years
    I just noticed something, after I added the meta tag to the view, I'm now seeing 2 values with the same token. The meta tag and a hidden input field with the name _token - both have the same value. Why am I seeing this? and why the ajax post wouldn't work without the meta tag even though the token already exists?
  • manix
    manix over 8 years
    That is because you are creating an html via \HTML::form function, by this way implicitly the function add a hidden input with the token as value. See edited answer.
  • Halnex
    Halnex over 8 years
    Yes, thank you. That also did it. So all I had to do was call the correct field.
  • manix
    manix over 8 years
    The use of <meta> is just necessary if you are not using HTML::form() function that make it automatically for you. That is why people use <meta> just when they create a form manually without the hidden input over a an over again the app.
  • ceejayoz
    ceejayoz over 8 years
    @Halnex I think that documentation has changed a bit since I last used it. I've updated mine to a non-meta tag version which'd be my preference usually.
  • scott
    scott over 8 years
    @manix.i am also facing same problem.i tried this example .even in this example also i am getting same error.if you know can you post here stackoverflow.com/questions/32203564/…
  • ira
    ira almost 8 years
    I confirm in that the 2nd solution ('X-CSRF-TOKEN': $('[name="_token"]').val()) worked pretty well in Laravel 5.2 using Laravel Collective forms