在 Laravel 5.1 中,Ajax Post 不起作用

3

我正在尝试在Laravel中使用ajax发布数据,但似乎无法正常工作。以下是我的代码:

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>                                     

和 route.php

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

在控制器中

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

    }

每当我尝试提交表单时,它都无法工作。我尝试使用onclick jQuery中的警报,但它显示警报消息。有人能告诉我为什么它不起作用吗?
注意:这个问题已经被问过了,但是没有找到任何对我有用的答案。
更新
<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>

在控制台安全性方面,我得到以下错误。
 [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');

文章控制器
public function store()
    {
        print_r(Request::all());

    }

enter image description here

更新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}  

“每当我尝试提交表单时都不起作用” - 这告诉我们很少的信息。什么没有工作?在您的浏览器中使用开发人员工具(特别是控制台和网络选项卡)。函数是否运行?是否有错误?请求是否被发出?它是否按您预期的格式进行格式化?您是否收到响应?响应是否按您预期的格式进行格式化?如果您手动向HTTP端点发出请求,它是否有效?您能否将问题缩小到JS或PHP? - Quentin
@tester,日志怎么样了?500错误可能有很多原因。 - manix
@manix。我已经添加了截图。 - scott
@manix,如果你知道这个问题的答案,能否发布一下?https://dev59.com/AI3da4cB1Zd3GeqP6vT2 - scott
不好意思,截图并不能说明问题。请查看/storage/logs/laravel-aug-28.log中打印的最后一个异常错误。 - manix
显示剩余5条评论
7个回答

5

你犯了多个错误:

1-你的csrf令牌在meta标签中(而不是在输入字段中):

2-meta标签名称为csrf_token(但你却用错误的名称调用它,即_token)

3-csrf令牌不在value属性中,而是在content属性中

因此,你必须像这样调用它

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

无论如何,有更简单的方法来实现这一点,如下所示:
 _token:"{{csrf_token()}}"

不必要:

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

请使用以下语句:

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

完整示例:

$.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')
        });

url: "{{route('routeName')}}", data: {_token:"{{csrf_token()}}", data: data}谢谢!这两行代码对我很有用。 - Akash Sethi

2
表单可以正常工作。
你只是忘记在ajax表单数据中发送"_method": "post"
Laravel使用Symfony路由,它使用一个特殊的参数叫做_ method来路由到你的路由定义。

不需要这样做。Ajax的头部已经使用“type”参数发送了POST方法。 - manix

2
我看到的是在ajax定义中调用了错误的URL,应该是:
url: 'http://localhost/demo/public/articles',

上面的URL应该存储一篇文章。登录后,您应该使用以下内容:

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

作为一条提示,如果您的网站将更改域名url,您可以通过javascript在头部初始化url:
<script>
    var login_url = '{{ url("login") }}';
</script>

那么您可以这样调用它:

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

1
正如您所看到的异常信息所示,您在CSRF令牌方面遇到了问题。因此,您无法发送令牌,这是您必须解决的问题。
在更新之前的初始问题中,您是通过隐藏的表单元素发送令牌,例如:'_token': $('input[name=_token]').val() Form::open应该在表单中添加字段,但可能出现了问题,因此建议您查看页面源代码,以确保存在类似于<input type="hidden" name="_token" value="asdfasfd">的隐藏表单元素。
或者您可以在浏览器控制台中键入$('input[name=_token]').val(),以确保您可以访问该值。
在“更新2”之后,您决定将CSRF令牌移动到元标记,并通过头发送它,但是元标记的名称为csrf_token,但您在$.ajax选项中引用它时使用了csrf-token(使用短划线而不是下划线)。

对于这两种情况,追踪问题的最佳方法是有效地使用浏览器控制台:

  • 当您在控制台看到错误时,只需单击链接,它将带您进入“网络”选项卡。
  • 您将在其中看到所有请求,请通过查看名称找到您的请求并单击它。(它应该会被突出显示一段时间,但有时它不可见,所以您可能需要向上或向下滚动来找到它)。
  • 在右侧单击“标头”选项卡,向下滚动以查看_token字段-或-X-CSRF-TOKEN标头以及它们是否为空。
  • 另一个提示是,单击“响应”或“预览”选项卡,以查看服务器响应,这样比转到日志等更快地检测错误。

1
我注意到了一些事情。首先,您在 routes.php 中设置了 POST 路由为“account/login”,但是您将 $.ajax url 设置为“login”。您需要将其设置为“/account/login”,就像您在表单 url 和(最重要的)路由文件中一样。
此外,因为您使用 Laravel {!! Form::xxx() !!} 结构,所以不需要包含“method”=>'POST'。这将自动添加给您,就像 CSRF Token 一样。http://laravelcollective.com/docs/5.0/html#opening-a-form 还有,您控制器中的“login”函数仅在请求不是 AJAX 时才运行,但您正在尝试通过 AJAX 请求发送它?这只是一些需要深入了解的事情。希望能有所帮助。

@DonnaJo,我犯了一个拼写错误。我的URL是正确的,即使我尝试了这个例子https://dev59.com/KI7ea4cB1Zd3GeqPCYnU,但仍然出现相同的错误。 - scott
如果我移除脚本,那么它会提交表单。我将在我的问题中更新新的示例。 - scott

0

我认为问题出在 App/Http/Middleware/Authenticate.php 文件中。尝试更改它。

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);
}

转换为这个:

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

如果 ($this->auth->guest()) { if ($request->ajax()) { return response('未授权。', 401); } else { return redirect()->guest('auth/login'); } }哈哈,那怎么可能是个答案?删除它看看会发生什么!几乎任何人都可以在API上运行函数。 - Gregory Bowers

0
问题在于您使用的是URL而不是直接路径。Laravel几乎会覆盖和重定向任何http post或get。打开浏览器的开发人员工具并查看请求,实际请求的URL与您的ajax调用中的URL不同。
请参见下面的示例,完整的URL不起作用。绝对路径可以。
$.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");
        });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接