【问题标题】:Laravel 5: Ajax Post 500 (Internal Server Error)Laravel 5:Ajax Post 500(内部服务器错误)
【发布时间】:2015-11-22 06:49:10
【问题描述】:

我正在尝试通过 ajax 向数据库提交数据。提交文章页面可以在没有 ajax 的情况下正常工作。我添加了console.log() 只是为了看看是否有任何事情发生,但我收到了这个错误:

POST http://localhost/laravel-5/public/articles/create 500(内部服务器错误)

我的代码有什么问题?是javascript还是控制器?

编辑:我在laravel.log得到这个

C:\xampp\htdocs\laravel-5\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:53 中的异常“Illuminate\Session\TokenMismatchException”:53

路线

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

控制器

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

查看

<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>

});

【问题讨论】:

  • 检查你的 Laravel/服务器日志,了解 500 是由什么引起的。
  • 这就是我得到的exception 'Illuminate\Session\TokenMismatchException' in C:\xampp\htdocs\laravel-5\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:53
  • @Halnex,你需要设置token,让我编辑答案
  • 您的会话结束了吗?在此之前:Auth::user()->articles()->save($article);使用 if(Auth::check()) { //这里是代码} 检查会话是否处于活动状态

标签: php jquery ajax laravel laravel-5


【解决方案1】:

当你通过 POST 向资源控制器发出请求时,它会自动调用 store 方法:

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

因此,您只需将 ajax url 更改为:

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

当您需要发送会话令牌时,您可以添加一个全局元标记,例如这是您的网站:

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

然后,只需通过 ajax 的标头添加令牌:

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

如果您使用 Form::open() 函数 (LaravelCollective),它会添加一个隐藏输入,其中包含名称为 _token 的标记作为值。因此,您可以删除元标记并编辑 ajax 的标题,如下所示:

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

【讨论】:

  • 我仍然遇到同样的错误。我只是检查 laravel 日志,我收到了这个错误 exception 'Illuminate\Session\TokenMismatchException' in C:\xampp\htdocs\laravel-5\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken.php:53
  • 感谢您在没有建设性意见的情况下投反对票 :)
  • 那是因为您正在通过\HTML::form 函数创建一个html,通过这种方式,该函数隐含地添加了一个隐藏的输入,其中令牌作为值。请参阅编辑后的答案。
  • &lt;meta&gt; 的使用是必要的,如果您不使用自动为您生成的HTML::form() 功能。这就是为什么人们只在手动创建表单时使用&lt;meta&gt;,而无需在应用程序上再次隐藏输入。
  • 我确认第二个解决方案 ('X-CSRF-TOKEN': $('[name="_token"]').val()) 在 Laravel 5.2 中使用 Laravel Collective 运行良好表格
【解决方案2】:

这就是我在 C:\xampp\htdocs\laravel-5\vendor\laravel\framework\src\Illuminate\Foundation\Htt‌​p\Middleware\VerifyCsrfToken.php:53 中得到的异常 'Illuminate\Session\TokenMismatchException'

你正在攻击 Laravel 的 CSRF 保护。

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

您需要传递隐藏的_token 字段的值。这可以通过在应用程序的 JS 中对所有 jQuery 发起的 AJAX 请求自动完成:

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

或者,您可以在每个 AJAX 调用中手动获取并传递 _token 隐藏字段的值。

【讨论】:

  • 谢谢,但在我看来,我仍然需要回答meta 标签。这一切都解决了。
  • @Halnex 我认为自从我上次使用它以来,文档已经发生了一些变化。我已经将我的更新为非元标记版本,这通常是我的偏好。
【解决方案3】:

我喜欢分享这段代码来帮助需要 ajax 发布并使用 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】:

    您可以将您的 URL 添加到 VerifyCsrfToken.php 中间件。这些 URL 将被排除在 CSRF 验证之外:

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

    【讨论】:

      【解决方案5】:

      好吧,如果您正在寻找可靠的答案,那就是: 如果您的代码中缺少 csrf_token(),则尤其会发生此错误 这是我所做的,

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

      现在使用 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>
      

      在我的 laravel 控制器中

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

      【讨论】:

        猜你喜欢
        • 2019-12-05
        • 2015-09-20
        • 2017-03-07
        • 1970-01-01
        • 2016-04-08
        • 2014-12-01
        • 2018-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多