Laravel 5: Ajax Post 500 (Internal Server Error)

2019-01-18 14:32发布

问题:

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>

});

回答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()
        }
});


回答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.



回答3:

I like to share this code to help someone to need ajax post and get with laravel

<<<<<<<<
POST
<<<<
<<look after @extends<<
<<look beforeSend: function (xhr) <<
<<look use Illuminate\Http\Request in Routes<< 
<<<------<<views\login\login.blade.php<<<<-----------<<<
@extends('cuerpito.web')
<meta name="csrf_token" content="{{ csrf_token() }}" />
@section('content')
  <form action="#" id="logForm" method="post" class="form-horizontal">
             <div class="form-group">
                <div class="col-xs-12">
                    <div class="input-group">
                        <input type="email" id="email" name="email" class="form-control input-lg" placeholder="Ingresa tu Email." autocomplete="off">                            
                    </div>
                </div>
            </div>


            <div class="form-group">
                <div class="col-xs-12">
                    <div class="input-group">
                         <input type="password" id="password" name="password" class="form-control input-lg" placeholder="Ingresa tu Contraseña." autocomplete="off">

                    </div>
                </div>
            </div>
            <div class="form-group formSubmit">
                <div class="col-xs-12">
                    <div class="input-group">
                        <button type="submit" name="feedbackSubmit" id="feedbackSubmit" class="btn btn-success btn-lg" style="display: block; margin-top: 10px;">Ingresar</button>
                    </div>
                </div>
            </div>
     </form>

   <script type="text/javascript">
         $(document).ready(function () {
          $("#feedbackSubmit").click(function () {
              $.ajax({
                url: '{{URL::route('login4')}}',
                type: "post",
                 beforeSend: function (xhr) {
        var token = $('meta[name="csrf_token"]').attr('content');

        if (token) {
              return xhr.setRequestHeader('X-CSRF-TOKEN', token);
        }
    },
                data: $("#logForm").serialize(),
                success: function (data)
                {
                    if (data) {
                        alert(data);
                        console.log(data);
                         } else {
                  console.log(data);
                    }//else 
                }//success
              });//ajax
            return false;
          });//feedbacksubmit
   });//document ready
 </script>  
  -------------0----------------------
  -------------0----------------------
<<<----<<app\Http\routes.php<<<<-----------<<<
 <?php
 use Illuminate\Http\Request;
 Route::post('login4', function()
{
    return 'Success! POST Ajax in laravel 5';
})->name('login4');

------------------0----------------------
------------------0----------------------
<<<<
Get
<<look after @extends<<
<<look beforeSend: function (xhr) <<
<<look use Illuminate\Http\Request in Routes<< 
<<<------<<views\login\login.blade.php<<<<-----------<<<
@extends('cuerpito.web')
<meta name="csrf_token" content="{{ csrf_token() }}" />
@section('content')
<form action="#" id="logForm" method="post" class="form-horizontal">
             <div class="form-group">
                <div class="col-xs-12">
                    <div class="input-group">
                        <input type="email" id="email" name="email" class="form-control input-lg" placeholder="Ingresa tu Email." autocomplete="off">                            
                    </div>
                </div>
            </div>


            <div class="form-group">
                <div class="col-xs-12">
                    <div class="input-group">
                         <input type="password" id="password" name="password" class="form-control input-lg" placeholder="Ingresa tu Contraseña." autocomplete="off">

                    </div>
                </div>
            </div>
            <div class="form-group formSubmit">
                <div class="col-xs-12">
                    <div class="input-group">
                        <button type="submit" name="feedbackSubmit" id="feedbackSubmit" class="btn btn-success btn-lg" style="display: block; margin-top: 10px;">Ingresar</button>
                    </div>
                </div>
            </div>
 </form>


  <script type="text/javascript">
       $(document).ready(function () {
        $("#feedbackSubmit").click(function () {
              $.ajax({
                url: '{{URL::route('login2')}}',
                type: "get",

                beforeSend: function (xhr) {
        var token = $('meta[name="csrf_token"]').attr('content');
        if (token) {
              return xhr.setRequestHeader('X-CSRF-TOKEN', token);
        }
    },    

                data: $("#logForm").serialize(),
                success: function (data)
                {
                    if (data) {
                        obj = JSON.stringify(data, null, "    ");
                        var datito = JSON.parse(obj);
                        console.log(datito.response);
                        alert(datito.response);

                    } else {
                        console.log(data);
                    }//else 
                }//success
            });//ajax
            return false;
        });//feedbacksubmit
});//document ready
 </script> 
  -------------0----------------------
  -------------0----------------------
    <<<----<<app\Http\routes.php<<<<-----------<<<
    <?php
    use Illuminate\Http\Request;
    Route::get('login2', 'WebController@login2')->name('login2');
  -------------0----------------------
  -------------0----------------------
    <<<----<<Http\Controllers\WebController.php<<<<-----------<<<
   public function login2(Request $datos) {
    if ($datos->isMethod('get')) {
        return response()->json(['response' => 'This is get method']);
    }
    return response()->json(['response' => 'This is post method']);
}

  -------------0----------------------
  -------------0----------------------


回答4:

You can add your URLs to the VerifyCsrfToken.php middleware. The URLs will be excluded from CSRF verification:

protected $except = [ "your url", "your url/abc" ];


回答5:

Well if you are looking for the sure shot answer ,here it is : This error particularly occurs if you are missing csrf_token() in your code Here is what I did,

<h6>ITEMS  ORDERED:<a href="#" id="{{$post->identifier}}" onclick="getcart(this.id)">CLICK HERE</a></h6>
<input type="hidden" id="token" value="{{ csrf_token() }}">

Now With Ajax

<script type="text/javascript">
function getcart(val) {
  var alpha=val;
var token=document.getElementById('token').value;

$.ajax({
 type:'post',
 url:'/private/getcart',
 data:{'alpha':alpha,'_token': token},//this _token should be as it is 
 success:function (result) {
alert(result);
 }

});


}

</script>

In my laravel controller

public function getcart(Request $req)
{
  return response ("its");
}