Прерывание отправки формы в блоке fetch
Выполняю проверки полей на стороне клиента на пробелы, на лишние символы и тд, в случае одного не совпадения форма не отправляется. Но при fetch запросе на наличие пользователя с данным логином все отрабатывает верно, но все равно форма отправляется. Почему так? я понимаю что проблема в том что fetch запрос асинхронный, но все равно победить это не могу.
<script>
function validateForm() {
const userName = document.getElementById("userName").value;
const password = document.getElementById("password").value;
const confirmPassword = document.getElementById("confirmPassword").value;
const firstName = document.getElementById("firstName").value;
const lastName = document.getElementById("lastName").value;
let rc = true;
fetch('/registration/check-username?userName=' + userName)
.then(response => response.json())
.then(data => {
if (!data) {
alert("Пользователь с таким логином уже существует");
rc = false;
}
});
if (userName.includes(" ") || password.includes(" ") || confirmPassword.includes(" ")
|| firstName.includes(" ") || lastName.includes(" ")) {
alert("Строки не могут содержать пробелы");
rc = false;
}
const regex1 = /^[A-Za-z0-9]+$/;
if (!(regex1.test(userName) && regex1.test(password) && regex1.test(confirmPassword))) {
alert("Логин и пароль могут содержать только английские символы и цифры");
rc = false;
}
const regex2 = /^[А-Яа-я]+$/;
if (!(regex2.test(firstName) && regex2.test(lastName))) {
alert("Имя и фамилия могут содержать только русские буквы");
rc = false;
}
if (password !== confirmPassword) {
alert("Введенные пароли не совпадают");
rc = false;
}
return rc;
}
</script>
Ответы (2 шт):
Если вы знаете, что fetch асинхронный, значит надо копать в эту сторону. Конкретнее: смотреть async/await, async/await in docs
В итоге функция будет уже такой:
async function validateForm() {
...
}
а работа с fetch примерно такой:
let response = await fetch('/registration/check-username?userName=' + userName);
let data = await response.json();
if (!data) {
alert("Пользователь с таким логином уже существует");
rc = false;
}
НО...тут может возникнуть проблема применения validateForm
.... в зависимости от того, где она стоИт и как применяется...Потому что функция тоже становится асинхронной и в месте её использования придётся тоже что-то модифицировать. Пример можно посмотреть тут
Опять же, тут придётся погрузиться в тему async/await
Ну потому что у вас сначала идёт отправка по fetch, а потом уже проверки. Просто измените последовательность. Сначала можете сделать все проверки с сохранением результата, а потом уже делать проверку на то, вернула ли какая-то проверка валидации значение false
. Тот же fetch закидывайте в какой-то if/else
с условием true
от всех валидаций, и только в этом случае делайте отправку
Но если вы используете fetch
как серверную валидацию (Что мне подсказали в комментариях), тут есть несколько моментов. Во-первых, отправка данных на сервер должна выполняться через HttpPost
запрос. Во вторых, вот стандартная схема для использования fetch
:
let response = await fetch('domain.com/url/')
let data = await response.json()
Вот статья о том, как делать fetch запрос