Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5: Ajax Post 500 (Internal Server Error)

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>

});

like image 336
Halnex Avatar asked Aug 27 '15 18:08

Halnex


2 Answers

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()
        }
});
like image 62
manix Avatar answered Nov 19 '22 10:11

manix


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.

like image 44
ceejayoz Avatar answered Nov 19 '22 11:11

ceejayoz