简体   繁体   中英

laravel cannot post data with ajax server status 419

I am doing a project with Laravel.

When I change the selected option of the following select element I should insert the selected value to mysql database to retrieve all the data about the selected id from the server (for example the name of the user).

This is the select element (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>

And this is the called function (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);
        }
    });
};

These are my routes (web.php):

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

And these are my controller methods (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'));
}

However, when I change the selected value nothing happens... and if I go to the developer tools I see the following error:

Failed to load resource: the server responded with a status of 419 (unknown status). Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException The GET method is not supported for this route. Supported methods: POST.

I don't see any alert. Someone can help me?

The HTTP status code for the MethodNotAllowedHttpException is 405

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

A TokenMismatchException HTTP status code is 419

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

So this appears to be a CSRF token issue

Make sure that you have a meta tag on the head of your document like this

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

Also from the JQuery Ajax Documentation

I think that the HTTP method should be defined as method parameter not type (though type works ¯\_(ツ)_/¯)

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

But now you're gonna get an error

Object of class Illuminate\Database\Eloquent\Builder could not be converted to string

Because you're trying to return a query builder instance User::where('id', $select) instead of the user record itself serialized

I think you may want to do this

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

Hope this helps

Try to 'method' instead of 'type'. You should use type if you're using versions of jQuery prior to 1.9.0

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

this is a CSRF protection of laravel, you can add csrf meta tag in the head

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

and in the top of the script write

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM