Я включил новую скрытую инфраструктуру reCAPTCHA (v2), которая по умолчанию проверяет пользователя с событием click
кнопки отправки. Но это событие запускается до проверки встроенной формы HTML5. Я ищу способ сделать это в ожидаемом порядке: сначала проверьте форму, reCAPTCHA после.
Подтверждение формы HTML5 перед reCAPTCHA
Ответ 1
Вы должны сделать это программно благодаря новому методу v2 grecaptcha
: grecaptcha.execute()
, чтобы recaptcha не заменил событие нажатия кнопки по умолчанию, которое препятствовало проверке формы HTML5 по умолчанию.
Путь к событию:
- Отправить событие нажатия кнопки: проверка встроенной формы браузера
- Форма отправить событие: call
grecaptcha.execute()
- Обратный вызов reCAPTCHA: отправьте форму
$('#form-contact').submit(function (event) {
event.preventDefault();
grecaptcha.reset();
grecaptcha.execute();
});
function formSubmit(response) {
// submit the form which now includes a g-recaptcha-response input
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js"></script>
<form action="?">
<div class="g-recaptcha"
data-sitekey="your-key"
data-size="invisible"
data-callback="formSubmit">
</div>
<button type="submit">Submit</button>
</form>
Ответ 2
Вот мое решение для проверки HTML5 + Invisible recaptcha:
HTML:
<form id="my-form">
<!-- Your form fields ... -->
<div class="g-recaptcha"
data-sitekey="..."
data-callback="submitMyForm"
data-size="invisible">
</div>
<button type="submit">Submit</button>
</form>
JS:
var myForm = $('my-form');
function submitMyForm () {
myForm.trigger('submit', [true]);
}
$(function () {
myForm.on('submit', function (e, skipRecaptcha) {
if(skipRecaptcha) {
return;
}
e.preventDefault();
grecaptcha.execute();
});
})
Ответ 3
Привет, здесь есть рабочее решение. Работа с невидимым Recaptcha.
jQuery(document).ready(function() {
var commentform = jQuery("#commentform");
commentform.on("click", "#submit-comment", function(e) {
if(commentform[0].checkValidity()) {
e.preventDefault();
grecaptcha.execute();
}
});
});
function submitCommentForm(data) {
document.getElementById("commentform").submit();
}
<form action="blaba.php" method="post" id="commentform" class="comment-form">
<div class="form-submit">
<div data-callback="submitCommentForm" data-sitekey="yourkey" class="g-recaptcha" data-size="invisible">
<button id="submit-comment">Leave a comment</button>
</div>
</form>
Ответ 4
Я хотел того же поведения, но с использованием новой recaptcha, невидимой. Посмотрев код и протестировав кое-что, я понял это. Основное отличие состоит в том, что здесь также используется проверка браузера по умолчанию:
var contact_form;
$(function() {
contact_form = $('#contact-form');
contact_form.submit(function (event) {
if ( ! contact_form.data('passed')) {
event.preventDefault();
grecaptcha.execute();
}
});
});
function sendContactForm(token) {
contact_form.data('passed', true);
contact_form.submit();
}
Это в основном сохраняет объект формы JQuery в глобальной переменной, в том числе, он использует sendContactForm
как обратный вызов, но при вызове рекапчи, он устанавливает вар данных с именем passed
, что позволяет форма не предотвратить. Это в точности то же самое поведение, которое обычно делает recaptcha, но с этим условием.
Обновление: пересмотр моего кода справа напоминает мне, что, вероятно, нужен способ восстановить данные, переданные в false
после выполнения grecaptcha. Учтите, что если вы это осуществите.
Ответ 5
let siteKey = "...";
$("form").submit(function (eventObj) {
var myForm = this;
eventObj.preventDefault();
grecaptcha.execute( siteKey, {
action: "submit"
})
.then(function (token) {
$('<input />').attr('type', 'hidden')
.attr('name', "g_recaptcha_response")
.attr('value', token)
.appendTo(myForm);
myForm.submit();
});
});
Это выполнит recapcha, дождется ответа, добавит скрытый атрибут g_recaptcha_response в любую форму, когда браузер попытается отправить его, а затем фактически отправит. Вам нужна глобальная переменная siteKey
Ответ 6
У меня была эта проблема, так как метод по умолчанию, кажется, переопределяет проверку формы HTML5. Я также хотел, чтобы весь код был общим, а не жестко кодировал имена любых функций/элементов. В конце я придумал следующий код, используя API v3 -
HTML
<form method="post" action="?" class="ui-recaptcha" name="my_form_name">
...
<input type="submit" value="Submit">
</form>
<script src="//www.google.com/recaptcha/api.js?render={key}" async defer></script>
Javascript (я использую jQuery, но его довольно легко адаптировать к vanilla js)
$('.ui-recaptcha').submit(e => {
var form = e.target;
if( $(form).data('recaptcha-done') )
return;
e.preventDefault();
grecaptcha.execute('{key}', {'action': $(form).attr('name')}).then(token => {
$(form).append($('<input>').attr({'type': 'hidden', 'name': 'g-recaptcha-response', 'value': token}));
$(form).data('recaptcha-done', true);
$(form).submit();
});
});
Я обнаружил, что простой вызов submit
как в некоторых приведенных выше примерах, вызвал для меня цикл, который имел бы смысл, поскольку обработчик recaptcha запускается в событии submit
.
Это запускает recaptcha для любой формы ui-recaptcha
, передает атрибут name
формы как действие, которое можно увидеть в консоли reCaptcha, а затем вставляет токен в форму. После запуска он устанавливает атрибут данных в форме, поэтому рекурсивный вызов submit не пытается снова запустить recaptcha.