Не удается обработать поля формы в ajax с помощью Laravel

#php #laravel

#php #laravel

Вопрос:

Я использую Laravel 7 и PHP 7.4. Я отправляю свою форму с помощью ajax-вызова и получаю ответ Json, показывающий соответствующие ошибки, если таковые имеются.

Я serialize() создаю форму в вызове ajax. Моя проблема в том, что я получаю 422 Unprocessable Entity против каждого поля, к которому я применил проверку.

Удивительно то, что если мое поле не пустое, я все равно получаю странную ошибку required.

Я обнаружил тот факт, что люди, которые сталкивались с этой проблемой в прошлом, либо переключились на другой подход, либо получили решение методом проб. Моя проверка соответствует документу Laravel.

Почему я получаю эту ошибку и каково правильное решение?

Вид блейда

 <form method="POST" name="register_name" id="register_forms" action="{{ route('verifydata') }}">
    @csrf
    <input placeholder="Name" id="register_name" type="text" />
    <input id="my-register" type="submit" value="Continue">
</form>
  

Javascript

 $("#my-register").click(function(e) {
    e.preventDefault();

    var _token = $('input[name="_token"]').val();
    var data = $('#register_forms').serialize()
    $.ajax({
        type: "post",
        url: "{{ url('verifydata') }}",
        data: {
            _token: _token,
            data: data
        },
        dataType: 'json',
        success: function(data) {
            $('#success_message').fadeIn().html(data.message);
        },
        error: function(err) {
            if (err.status == 422) { // when status code is 422, it's a validation issue
                console.log(err.responseJSON);
                $('#success_message').fadeIn().html(err.responseJSON.message);

                console.warn(err.responseJSON.errors);
                $.each(err.responseJSON.errors, function(i, error) {
                    var el = $(document).find('[name="'   i   '"]');
                    el.after($('<span style="color: red;">'   error[0]   '</span>'));
                });
            }
        }
    });
    /**Ajax code ends**/
});
  

Контроллер

 public function verifydata(Request $request)
{
    $this->validate($request, [
        'name' => 'required', 'string', 'max:255',
    ]);

    $name = $request->register_name;

    return response()->json([
        'message' => $name
    ]);
}
  

Комментарии:

1. 'name' => 'required', 'string', 'max:255', вероятно, должен быть массив 'name' => ['required', 'string', 'max:255'] laravel.com/docs/7.x/validation

2. @kerbh0lz Все еще написано «422 необработанных объекта».

Ответ №1:

Прежде всего, попытайтесь понять, какую ошибку вы получаете, поэтому прочитайте это

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422

Код состояния ответа необработанного объекта HyperText Transfer Protocol (HTTP) 422 указывает, что сервер понимает тип содержимого объекта запроса, и синтаксис объекта запроса правильный, но он не смог обработать содержащиеся инструкции.

Я вижу три ошибки:

Первое: вы сообщаете в своем запросе, что отправляете данные в формате JSON, что не соответствует действительности

 dataType: 'json',
  

Потому что .serialize() генерирует не JSON, а сериализованное тело POST

ЭТО выглядит так: имя =kamilamp; фамилия = kamil

Итак, удалите тип данных: ‘json’ и добавьте это к данным

 data : $('#register_forms').serialize()   "amp;_token="   _token
  

Если вы хотите отправить данные в формате JSON, вам необходимо создать данные в формате JSON.

Sedcond: у вас нет атрибута «name» в ваших «входных данных».

 <form method="POST" name="register_name" id="register_forms" action="{{ route('verifydata') }}">
    <input placeholder="Name" name="register_name" id="register_name" type="text" />
    <input id="my-register" type="submit" value="Continue">
</form>
  

Третье: в вашем PHP-коде, где вам нужно указать правила проверки, подобные этому

https://laravel.com/docs/7.x/validation

Итак, это:

 $this->validate($request, [
    'name' => ['required', 'string', 'max:255'],
]);
  

Или это

 $this->validate($request, [
    'name' => 'required|string|max:255',
]);
  

После исправления это должно сработать.

Комментарии:

1.К вашему сведению, согласно документам $.ajax dataType , это ответ, а не запрос. 🙂

2. Верно, если я хочу получить ответ в формате json, мне пришлось бы определить тип данных: json.

3. Я только что добавил эту строку «data: $ (‘#register_forms’).serialize() «amp;_token =» _token», и моя проблема на 50% решена, и если мое поле имеет значение, то ajax возвращает статус 200 ok. …….. Теперь проблема в том, что когда я оставляю поле пустым, оно возвращает ошибку «422 Необработанный объект», что означает, что моя проверка не работает!

Ответ №2:

Есть пара проблем с предоставленным вами кодом.

Вы не предоставили name атрибут для вашего <input /> . Измените свой <input /> на:

 <input name="name" placeholder="Name" id="register_name" type="text"/>
  

Назначьте сериализованные данные непосредственно data атрибуту, а не внутри объекта:

 $.ajax({
    type: 'POST',
    url: "{{ url('verifydata') }}",
    data: data,
    dataType: 'json',
    ...
});
  

Имеющийся у вас код (при условии, что поле ввода имеет имя) приведет к следующему на сервере:

 [
    '_token' => 'cqmRx74gJiSXyAFXBdq5UagX68O6OvYqX67WwIAZ',
    'data'   => '_token=cqmRx74gJiSXyAFXBdq5UagX68O6OvYqX67WwIAZamp;name=foobar' 
]
  

Сериализованные данные не будут проанализированы, если это дочерний атрибут тела.

Кроме того, вам не нужно добавлять _token атрибут, поскольку он уже должен быть включен в вашу форму с момента использования @csrf .


Наконец, либо оберните ваши правила проверки в массив:

 $this->validate($request, [
    'name' => ['required', 'string', 'max:255'],
]);
  

или одна строка, разделенная каналами ( | ):

 $this->validate($request, [
    'name' => 'required|string|max:255'],
]);
  

Комментарии:

1. Я выполнил все рекомендованные вами шаги. Я только что удалил токен из моего вызова ajax, и он начал выдавать ошибку «Код статуса: 419 неизвестный статус». После добавления токена моя проблема вернулась, поэтому я думаю, что токен здесь обязателен.

2. @Shaan Вы удалили @csrf директиву из формы? Если это так, вам нужно будет вернуть его обратно.

3. Нет, я просто удалил _token согласно вашей инструкции из моего ajax-вызова. В моем коде был @csrf, и я получил ошибку, как я уже сказал.

4. @Shaan О, это странно. Я только что протестировал его локально, и он должен работать нормально, так как @csrf добавит _token поле в вашу форму и serialize() также должен включать эти данные. Я бы посоветовал проверить вкладку сеть в вашем браузере, чтобы убедиться, что она не включена. Если это так, то вам, вероятно, потребуется выполнить жесткое обновление.

5. @Shaan … в качестве альтернативы вы могли бы вместо этого включить токен в качестве заголовка: laravel.com/docs/7.x/csrf#csrf-x-csrf-toke