#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/validation2. @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