Google невидимый reCaptcha + jQuery validate() проблема
Я успешно реализовал новую невидимую reCaptcha от Google на нескольких сайтах, однако она конфликтует с jQuery validate() таким образом, что проверка js больше не выполняется при отправке с помощью кнопки / формы, и reCaptcha мгновенно запускается. Если пользователь забудет заполнить обязательное поле формы, ему придется дождаться ответа сервера и вернуться к нему в следующий раз.
jQuery.validate () поддерживает обратный вызов, но из-за того, что он жестко запрограммирован во внутреннем классе CMS, есть способ, которым я могу как-то изменить его снаружи (например, из внешней темы, при загрузке документа, когда код проверки уже предоставлен)?
Или другой идеей было бы как-то отложить обратный вызов капчи, чтобы шаг проверки мог получить шанс на запуск.
Спасибо!
Форма jQuery Validate: (жестко запрограммирована в ядре, не может быть изменена, если я не редактирую файл ядра или не расширяю функцию класса / клона - не оптимально)
<script type="text/javascript">
$(document).ready(function(){
$("form[name=comment_form]").validate({
rules: {
body: {
required: true,
minlength: 1
},
authorEmail: {
required: true,
email: true
}
},
wrapper: "li",
errorLabelContainer: "#comment_error_list",
invalidHandler: function(form, validator) {
$('html,body').animate({ scrollTop: $('#comment_error_list').offset().top }, { duration: 250, easing: 'swing'});
},
submitHandler: function(form){
$('button[type=submit], input[type=submit]').attr('disabled', 'disabled');
form.submit();
}
});
});
</script>
reCaptcha явный рендер:
<script type='text/javascript'>
var renderInvisibleReCaptcha = function() {
for (var i = 0; i < document.forms.length; ++i) {
var form = document.forms[i];
var holder = form.querySelector('.invisible-recaptcha');
if (null === holder) continue;
(function(frm){
var holderId = grecaptcha.render(holder, {
'sitekey': 'my-key-here',
'badge': 'inline',
'size': 'invisible',
'callback': function (recaptchaToken) {HTMLFormElement.prototype.submit.call(frm);},
'expired-callback': function(){grecaptcha.reset(holderId);}
});
frm.onsubmit = function (evt){evt.preventDefault();grecaptcha.execute(holderId);};
})(form);
}
};
</script>
4 ответа
У меня была та же проблема, я, наконец, нашел правильный способ интеграции проверки JQuery с невидимым reCaptcha. Это сочетание некоторых из предлагаемых решений здесь.
Прежде всего, HTML часть:
<div class="g-recaptcha" data-sitekey="<your key here>"
data-size="invisible"
data-callback="formSubmit">
Затем вы должны реализовать обратный вызов reCaptcha следующим образом:
function formSubmit(response) {
// submit the form which now includes a g-recaptcha-response input
$("#orderform").submit();
return true;
}
И, наконец, сложная часть находится в submitHandler проверки JQuery:
submitHandler: function (form) {
if (grecaptcha.getResponse()) {
// 2) finally sending form data
form.submit();
}else{
// 1) Before sending we must validate captcha
grecaptcha.reset();
grecaptcha.execute();
}
}
Последовательность следующая:
- Когда пользователь нажимает кнопку подтверждения, вызывается submitHandler в jquery, поскольку невидимая рекаптча еще не выполнена, мы вызываем grecaptcha.execute(). Для проверки recaptcha от Google требуется несколько секунд, и когда он будет полностью проверен, он вызовет обратный вызов formSubmit (пока этот обратный вызов не вызывается, мы не можем отправить данные формы на сервер!).
- В обратном вызове formSubmit мы вызываем $('#orderform'). Submit для принудительного повторного ввода submitHandler.
- Снова в submitHandler, на этот раз, поскольку grecaptcha.getResponse не равен нулю, мы можем опубликовать данные формы на сервере, они будут включать скрытое поле recaptcha, которое затем должно быть проверено на стороне сервера.
Надеюсь это поможет.
У меня была похожая проблема, и я проверил форму перед выполнением невидимой reCaptcha по этой ссылке, предоставленной Терри.
Вот шаги:
Добавьте этот div перед кнопкой отправки в вашей форме
<div id='recaptcha' class="g-recaptcha"
data-sitekey="your_site_key"
data-callback="onSubmit"
data-size="invisible"></div>
Также обновите ваш ключ. После закрытия формы добавьте этот метод
<script>onload();</script>
Перед формой добавьте этот код
<script>
function validate(event) {
event.preventDefault();
if (!document.getElementById('field').value) {
alert("You must add text to the required field");
} else {
grecaptcha.execute();
}
}
function onload() {
var element = document.getElementById('submit');
element.onclick = validate;
}
</script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
Выполните все проверки в методе validate, и если все проверки пройдены успешно, выполните команду captcha.
Технически все, что мы "действительно" хотим сделать, это программно связать вызов с кнопкой. Например:
Добавьте этот метод, который мы хотим только выполнить невидимую grecaptcha вместо "реальной" проверки
jQuery.validator.addMethod("iv_recapcha_valid", function(value, element) {
return grecaptcha.execute();
}, 'No message needed, grecaptcha excecuted');
Затем добавьте это правило в ваши существующие правила
rules: { gRecaptchaResponse: { iv_recapcha_valid: true } }
добавить скрытое поле
<input type="hidden" name="gRecaptchaResponse" value="" >
Теперь "технически" кнопка "Отправить" привязана к клику пользователя.
Что мне помогло, так это использование jquery, чтобы выбрать форму (я использовал getElementByID), а затем "вернуть true". Итак, вместо этого:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
function onSubmit(token) {
document.getElementById("frm").submit();
}
</script>
<button class="g-recaptcha btn btn-block btn-primary" data-sitekey="<YOUR_KEY>" data-callback='onSubmit'>Submit</button>
использовать этот:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
function onSubmit(token) {
$("#frm").submit();
return true;
}
</script>
<button class="g-recaptcha btn btn-block btn-primary" data-sitekey="<YOUR_KEY>" data-callback='onSubmit'>Submit</button>
У меня была такая же проблема при работе с классическим шаблоном Asp.Net Core MVC. Он был внутренне украшен ненавязчивым утверждением. После вставки невидимой recaptcha проверка была нарушена. Прочитав эту статью, мне удалось заставить ее работать, используя встроенную проверку, без необходимости указывать проверку для каждого поля (выведено из класса модели в проект MVC)
HTML-страница:
<input type="hidden" name="gRecaptchaResponse" id="gRecaptchaResponse" value="" />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div id='recaptcha' class="g-recaptcha"
data-sitekey="@_configuration["InvisibleRecaptcha:SiteKey"]"
data-callback="SubmitRegistration"
data-size="invisible"></div>
<button type="submit" id="SubmitButton" class="btn btn-primary"> Invia</button>
</div>
</div>
Код Javascript:
<script>
function onload() {
var element = document.getElementById('SubmitButton');
element.onclick = validate;
}
onload();
function validate(event) {
event.preventDefault();
$("#Form").validate();
var isFormValid = $("#Form").valid();
if (isFormValid) {
grecaptcha.execute();
}
}
function SubmitRegistration(data) {
if ($("#gRecaptchaResponse").val() == '') {
$("#gRecaptchaResponse").val(data);
}
document.getElementById("Form").submit();
}
</script>
Надеюсь, этот кусок кода может помочь кому-то
Я столкнулся с этим при использовании.NET Razor Pages, который по умолчанию использует проверку jquery. Большинство вышеперечисленных решений вызывают ввод кода капчи вручную. Я хотел использовать подход " Автоматическая привязка к кнопке". Это приведет к запуску captcha в первую очередь, и если мы успешно получим токен captcha, я бы запустил проверку jquery и, возможно, отправил форму. По умолчанию этот подход автоматического связывания нарушает триггеры проверки jquery.
Установите кнопку для ввода капчи
<button type="submit" class="btn primary-btn g-recaptcha h-100"
data-callback='onSubmit'
data-sitekey='@Model.CaptchaKey'
data-error-callback="onCaptchaError"
data-badge="inline"
data-action='submit'>
Submit <i class="fas fa-chevron-right"></i>
</button>
Обработка событий капчи для успеха / неудачи
<script src="https://www.google.com/recaptcha/api.js"></script>
<script>
function onSubmit(token) {
//Once we get a valid Captcha code, let's verify the form's unobtrusive validation
$("#your-form-id").validate();
var validationResult = $("#your-form-id").valid();
if (validationResult) {
//If we are valid, submit! Otherwise errors will show and we don't want to submit
document.getElementById("your-form-id").submit();
}
}
function onCaptchaError() {
alert("We had some trouble accessing captcha resources. Please refresh the page and try again.");
}
</script>
Дополнительный кредит: Стиль капча значок Убедитесь, что вы будете следовать политике Google по этому Хотя
.grecaptcha-badge {
visibility: hidden;
}