Фронтенд
2. Теперь создадим JavaScript-файл script.js, который будет отвечать за функционал слайдера, перетаскивание и верификацию через сервер. Создадим переменную captchaSession, в которой будет храниться ID текущей сессии капчи, полученной от сервера, чтобы потом использовать этот ID для валидации на сервере:
let captchaSession = "";
3. Загрузка сессии капчи с сервера:
function fetchCaptchaSession() {
fetch("http://localhost:3000/generate-slider-captcha")
.then((response) => response.json())
.then((data) => {
captchaSession = data.sessionId;
})
.catch((error) => console.error("Ошибка загрузки капчи:", error));
}
Здесь мы:
- Делаем fetch-запрос на http://localhost:3000/generate-slider-captcha.
- Ожидаем от сервера JSON с полем sessionId.
- Сохраняем этот sessionId в переменную captchaSession.
- Если происходит ошибка — выводит сообщение в консоль.
- Это нужно, чтобы позже передать sessionId на проверку в verify-slider.
4. Далее получаем доступ к нужным HTML-элементам:
const slider = document.getElementById("slider");
const button = document.getElementById("sliderButton");
const successMessage = document.getElementById("successMessage");
const errorMessage = document.getElementById("errorMessage");
let isDragging = false;
let sliderCompleted = false;
isDragging – следит, активен ли режим перетаскивания.
sliderCompleted – предотвращает повторные действия, если капча уже пройдена.
5. Обработаем нажатие мыши на ползунок:
button.addEventListener("mousedown", () => {
if (sliderCompleted) return;
isDragging = true;
});
Когда нажимается кнопка мыши на ползунке, проверяется, прошёл ли пользователь уже капчу. Если нет – включается режим перетаскивания (isDragging = true).
6. Перемещение ползунка:
document.addEventListener("mousemove", (e) => {
if (!isDragging) return;
let rect = slider.getBoundingClientRect();
let offsetX = e.clientX - rect.left;
if (offsetX < 0) offsetX = 0;
if (offsetX > rect.width - button.offsetWidth)
offsetX = rect.width - button.offsetWidth;
button.style.left = offsetX + "px";
});
Когда мышь двигается, проверяем, включён ли режим drag, вычисляем координаты мыши относительно слайдера. Значение ограничивается границами слайдера. Устанавливаем left у кнопки (ползунка), чтобы она двигалась.
7. Завершаем действие отпусканием мыши:
document.addEventListener("mouseup", () => {
if (!isDragging) return;
isDragging = false;
let rect = slider.getBoundingClientRect();
let finalPosition = parseInt(button.style.left);
Проверяем, происходило ли перетаскивание, выключаем режим isDragging, получаем конечную позицию ползунка. И проверяем, дошёл ли ползунок до конца:
if (finalPosition >= rect.width - button.offsetWidth - 5) {
8. Отправка на сервер (успешное выполнение):
fetch("http://localhost:3000/verify-slider", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ sessionId: captchaSession, completed: true }),
})
Отправляем POST-запрос на /verify-slider. В теле запроса указываем:
sessionId – ID сессии.
completed: true – пользователь довёл ползунок до конца.
9. Обрабатываем ответ
Если сервер ответил success: true:
- Показывается сообщение об успехе.
- Кнопка меняет цвет.
- Капча считается завершённой.
Если сервер ответил ошибкой:
- Показывается сообщение об ошибке.
- Ползунок сбрасывается.
- Загружается новая капча.
.then((response) => response.json())
.then((result) => {
if (result.success) {
successMessage.style.display = "block";
errorMessage.style.display = "none";
button.style.background = "green";
sliderCompleted = true;
} else {
successMessage.style.display = "none";
errorMessage.style.display = "block";
button.style.left = "0px";
fetchCaptchaSession();
}
})
10. Можем также добавить обработку ошибок запроса: сбрасываем ползунок, запрашиваем новую капчу:
.catch((error) => {
console.error("Ошибка при проверке капчи:", error);
errorMessage.style.display = "block";
button.style.left = "0px";
fetchCaptchaSession();
});
11. Ползунок не дошёл до конца. Если пользователь не довёл до конца – ползунок сбрасывается обратно влево:
} else {
button.style.left = "0px";
}
});
fetchCaptchaSession();