【问题标题】:laravel cannot post data with ajax server status 419laravel 无法使用 ajax 服务器状态 419 发布数据
【发布时间】:2020-02-12 16:26:58
【问题描述】:

我正在用 Laravel 做一个项目。

当我更改以下 select 元素的选定选项时,我应该将选定的值插入 mysql 数据库,以从服务器检索有关选定 id 的所有数据(例如用户名)。

这是选择元素(adminArea.blade.php):

<select name="employees" onchange="fillEmployeeData(this)" class="form-control col-sm-6" id="employees">
    <option value="0"></option>
    @foreach ($users as $user)
    <option value="{{ $user->id }}">{{ $user->surname . ' ' . $user->name }}</option>
    @endforeach
</select>

这是被调用的函数 (adminArea.blade.php)::

function fillEmployeeData(emp_id) {
    var emp_selected = emp_id.value;
    $.ajax({
        type: "POST",
        url: "{{ route('adminAreaPostEmployee') }}",
        data: 'emp_selected=' + emp_selected,
        success: function (data) {
            var emp_data = JSON.parse(data);
            alert(emp_data);
        }
    });
};

这些是我的路线(web.php):

Route::get('/adminarea', 'AdminAreaController@index')->name('adminArea');
Route::post('/adminarea/postemployee', 'AdminAreaController@post_employee')->name('adminAreaPostEmployee');

这些是我的控制器方法(adminAreaController.php):

public function post_employee(Request $request)
{
    $select = $request->get('emp_selected');
    $user = User::where('id', $select);
    echo $user;
}

public function index()
{
    $operations = Operation::all();
    $users = User::all()->sortBy('surname');
    $rooms = Room::all();
    return view('adminArea', compact('users', 'rooms', 'operations'));
}

但是,当我更改所选值时,什么也没有发生...如果我转到开发人员工具,我会看到以下错误:

加载资源失败:服务器响应状态为 419 (未知状态)。 Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException 此路由不支持 GET 方法。支持的方法: 发布。

我没有看到任何警报。有人可以帮助我吗?

【问题讨论】:

  • adminAreaController 是错字吗?因为它应该是AdminAreaController
  • 我无法重现,您使用的是哪个版本的 Laravel 和 JQuery?
  • 也尝试清除您的路线php artisan route:clear
  • 是的,这是一个错字!

标签: javascript php ajax laravel request


【解决方案1】:

MethodNotAllowedHttpException 的 HTTP 状态代码是 405

见here

public function __construct(array $allow, string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
    $headers['Allow'] = strtoupper(implode(', ', $allow));
    parent::__construct(405, $message, $previous, $headers, $code);
}

TokenMismatchException HTTP 状态码是419

见here

protected function prepareException(Exception $e)
{
    if ($e instanceof ModelNotFoundException) {
        $e = new NotFoundHttpException($e->getMessage(), $e);
    } elseif ($e instanceof AuthorizationException) {
        $e = new AccessDeniedHttpException($e->getMessage(), $e);
    } elseif ($e instanceof TokenMismatchException) {
        // HTTP Status code is send in the header here
        $e = new HttpException(419, $e->getMessage(), $e);
    } elseif ($e instanceof SuspiciousOperationException) {
        $e = new NotFoundHttpException('Bad hostname provided.', $e);
    }
    return $e;
}

所以这似乎是一个 CSRF 令牌问题

确保您的文档头部有这样的元标记

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

同样来自JQuery Ajax Documentation

我认为HTTP方法应该定义为method参数而不是type(虽然type有效¯\_(ツ)_/¯)

// Send a CSRF token header with every Ajax request
$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});
function fillEmployeeData(emp_id) {
    var emp_selected = emp_id.value;
    $.ajax({
        method: "POST",
        url: "{{ route('adminAreaPostEmployee') }}",
        data: 'emp_selected=' + emp_selected,
        success: function (data) {
            var emp_data = JSON.parse(data);
            alert(emp_data);
        }
    });
};

但是现在你会得到一个错误

Illuminate\Database\Eloquent\Builder 类的对象无法转换为字符串

因为您尝试返回查询构建器实例 User::where('id', $select),而不是序列化的用户记录本身

我想你可能想这样做

public function post_employee(Request $request)
{
    $select = $request->get('emp_selected');
    return User::find($select);
}

希望对你有帮助

【讨论】:

    【解决方案2】:

    尝试使用“方法”而不是“类型”。如果您使用的是 1.9.0 之前的 jQuery 版本,则应该使用 type

    function fillEmployeeData(emp_id) {
        var emp_selected = emp_id.value;
        $.ajax({
            method: "POST",
            url: "{{ route('adminAreaPostEmployee') }}",
            data: 'emp_selected=' + emp_selected,
            success: function (data) {
                var emp_data = JSON.parse(data);
                alert(emp_data);
            }
        });
    };
    

    【讨论】:

      【解决方案3】:

      这是 laravel 的一个 CSRF 保护, 您可以在头部添加 csrf 元标记

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

      并在脚本顶部写

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

      【讨论】:

        猜你喜欢
        • 2019-10-22
        • 2019-05-18
        • 2018-07-18
        • 1970-01-01
        • 2016-02-11
        • 2020-05-11
        • 1970-01-01
        • 2019-03-29
        • 1970-01-01
        相关资源
        最近更新 更多