scott
scott

Reputation: 3202

Ajax Post not Working in laravel 5.1

I am trying to post data using ajax in laravel but it seems to be not working. I have followed following is my code

login.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="csrf_token" content="{{ csrf_token() }}" />

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> 
<style type="text/css">

</style>
<script type="text/javascript">
$(document).ready(function(){
  $('.send-btn').click(function(){   
  console.log($('input[name=email]').val());
    $.ajax({
      url: 'login',
      type: "post",
      data: {'email':$('input[name=email]').val(), '_token': $('input[name=_token]').val()},
      success: function(data){
      console.log($('input[name=email]').val());
        alert(data);
      }
    });      
  }); 


});
</script>
</head>
<body>
<div class="secure">Secure Login form</div>
{!! Form::open(array('url'=>'account/login','method'=>'POST', 'id'=>'myform')) !!}
<div class="control-group">
  <div class="controls">
     {!! Form::text('email','',array('id'=>'','class'=>'form-control span6','placeholder' => 'Email')) !!}
  </div>
</div>
<div class="control-group">
  <div class="controls">

  </div>
</div>
{!! Form::button('Login', array('class'=>'send-btn')) !!}
{!! Form::close() !!}
</body>
</html>                                     

and route.php

Route::get('account/login', function() {
  return View::make('login');
});
Route::post('account/login', 'AccountController@login');

and in controller

 public function login() {
    // Getting all post data
    if(!Request::ajax()) {
      $data = Input::all();
      print_r($data);
    }

    }

Whenever I try to submit form not working. I tried using alert in onclick jquery but it shows alert message. Can anyone tell why it's not working?

Note: This question already asked but not found any answer useful for me

Laravel 5.1 ajax not working?

Update

<script type="text/javascript">
$(document).ready(function(){
  $('.send-btn').click(function(){   
  console.log($('input[name=email]').val());
    $.ajax({
      url: 'login',
      type: "post",

      data: {'email':$('input[name=email]').val(), '_token': $('input[name=_token]').val(),'_method': 'POST'},
      success: function(data){
      console.log($('input[name=email]').val());
        alert(data);
      }
    });      
  }); 


});
</script>

In console security i get following error

 [HTTP/1.0 500 Internal Server Error 115ms]


Update 2


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="csrf_token" content="{{ csrf_token() }}">

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> 
<style type="text/css">

</style>

<script>
$(document).ready(function() {
    $('#frm').on('submit', function (e) {
    alert();
        e.preventDefault();
        var title = $('#title').val();
        var body = $('#body').val();
        var published_at = $('#published_at').val();
        $.ajax({
            type: "POST",
            url: 'http://localhost/demo/public/articles/articles',
            headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        },
            dataType: 'JSON',
            data: {title: title, body: body, published_at: published_at},
            success: function( data ) {
                $("#ajaxResponse").append(data.msg);
                alert(data);
            }
        });
    });
    });
</script>
</head>
<body>

{!! 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() !!}

</body>
</html>   

route.php

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

Article controller

public function store()
    {
        print_r(Request::all());

    }

enter image description here

Update 2

[2015-08-28 06:23:03] 

local.ERROR: exception 'Illuminate\Session\TokenMismatchException' in D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:53
Stack trace:
#0 [internal function]: Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
#1 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(124): call_user_func_array(Array, Array)
#2 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\View\Middleware\ShareErrorsFromSession.php(54): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#3 [internal function]: Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#4 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(124): call_user_func_array(Array, Array)
#5 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php(62): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#6 [internal function]: Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#7 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(124): call_user_func_array(Array, Array)
#8 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#9 [internal function]: Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#10 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(124): call_user_func_array(Array, Array)
#11 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\EncryptCookies.php(59): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#12 [internal function]: Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
#13 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(124): call_user_func_array(Array, Array)
#14 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode.php(42): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#15 [internal function]: Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#16 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(124): call_user_func_array(Array, Array)
#17 [internal function]: Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#18 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(103): call_user_func(Object(Closure), Object(Illuminate\Http\Request))
#19 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(122): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#20 D:\xampp\htdocs\demo\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(87): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#21 D:\xampp\htdocs\demo\public\index.php(54): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#22 {main}  

Upvotes: 3

Views: 17480

Answers (7)

Gregory Bowers
Gregory Bowers

Reputation: 806

The problem is that you are using a URL instead of a direct path. Laravel pretty much overrides and redirects anything http post or get. Open up your browsers developer tools and look at the request, the URL that was actually requested is different than the one in your ajax call.

See example below, full URL DOES NOT WORK. Absolute path does.

$.ajax
        ({
            type: "POST",
            dataType : 'text',
            url: "../../public/head-editor-api/index.php", 
            data: {
                website_hosting_server: website_hosting_server,
                website_hosting_username: website_hosting_username,
                website_hosting_password: website_hosting_password
            }
        }).done( function(data){
            alert(data);
        }).fail(function(){
           alert("error");
        });

Upvotes: 0

Afraz Ahmad
Afraz Ahmad

Reputation: 5386

You are doing multiple mistakes:

1-your csrf token is in meta tag (not in input field):

2-meta tag name is csrf_token (but you are calling it with wrong name i.e _token)

3- csrf token is not in value attribute but it is in content attribute

So you have to call it like this

_token': $('meta[name=csrf_token]').attr('content')

Anyhow There is much easier way to do this as shown below:

 _token:"{{csrf_token()}}"

No need of it:

_token: $('meta[name=csrf_token]').attr('content')

Use this statement instead:

_token:"{{csrf_token()}}" will do the same.

Full Example:

$.ajax
        ({
            type: "POST",
            dataType : 'json',
            url: "{{route('routeName')}}", 
            data: {_token:"{{csrf_token()}}", data: data}
        }).done( function(data){
            console.log('Ajax was Successful!')
            console.log(data)
        }).fail(function(){
            console.log('Ajax Failed')
        });

Upvotes: 5

Nico Orfi
Nico Orfi

Reputation: 173

I think that the problem is in App/Http/Middleware/Authenticate.php Try changing this

public function handle($request, Closure $next)
{
    if ($this->auth->guest())
    {
        if ($request->ajax())
        {
            return response('Unauthorized.', 401);
        }
        else
        {
            return redirect()->guest('auth/login');
        }
    }

    return $next($request);
}

To this:

public function handle($request, Closure $next)
{
    return $next($request);
}

Upvotes: 0

madpoet
madpoet

Reputation: 1063

As you can see from the exception, you're having a problem with the CSRF token. So somehow you are not able to send the token, that's what you must track down.

In the original question before the updates, you're sending the token from the hidden form element like: '_token': $('input[name=_token]').val()

Form::open is supposed to add the field in the form but probably there was a problem the so I'd advise you to view the source of the page to make sure that there is a hidden form element like <input type="hidden" name="_token" value="asdfasfd">.

And/or you can just type $('input[name=_token]').val() in your browser's console to make sure that you can reach the value.


After 'update 2' you decided to move the CSRF token to the meta tag and send it with headers but the name of the meta is csrf_token however you're referencing it in the $.ajax options as csrf-token (dash instead of underscore is used).


For both of the cases, best way to track down the issue is using your browsers console effectively:

  • When you see the error in the console, just click on the link and it'll take you to the "network" tab.
  • You'll see all the requests in there, find your request by looking at the name and click it. (It should be highlighted for a moment but sometimes it's not visible so you might need to scroll up or down to find it).
  • At the right side click on "headers" tab and scroll down to see the _token field -or- X-CSRF-TOKEN header and if they're empty or not.
  • Another tip is, click on "response" or "preview" tab to see the server response, it's quicker to detect the error that way instead of going to the logs etc.

Upvotes: 1

manix
manix

Reputation: 14747

What I see is a wrong url called in ajax definition, should be:

url: 'http://localhost/demo/public/articles',

The url above should store an article. For post login you should use:

url: 'http://localhost/demo/public/login',

As a note, if your website will change the domain url, you could initialize the url via javascript in the header:

<script>
    var login_url = '{{ url("login") }}';
</script>

Then you can call it as:

$.ajax({
        type: "POST",
        url: login_url,

Upvotes: 2

DonnaJo
DonnaJo

Reputation: 538

I'm noticing a couple of things right off the bat. First and foremost, you have set your POST route (in routes.php) to 'account/login', but you are setting your $.ajax url to 'login'. You need to set it to '/account/login', just like you have it in your form url and (most importantly) routes file.

Also, because you are using the Laravel {!! Form::xxx() !!} structure, you do not need to include 'method'=>'POST'. That will be added for you automatically, as will the CSRF Token. http://laravelcollective.com/docs/5.0/html#opening-a-form

Also, the 'login' function in your Controller is only running if the request is not AJAX, but you're trying to send through an AJAX request, correct? Just a couple of things to delve into. Hope it helps.

Upvotes: 1

ChainList
ChainList

Reputation: 1208

The form is perfectly working.

You just forget to send "_method": "post" in your ajax form data. Laravel is using Symfony routing which uses a special parameter called _ method to route to your route definition.

Upvotes: 2

Related Questions