目前,grecaptcha.execute
正在页面加载时执行,如下面的第一个JS示例所示。如果触发了reCAPTCHA质询,则会在页面加载后发生。理想情况下,这将在单击表单提交按钮时发生。
因此,我尝试通过将其移入Submit事件(第二个JS示例)并将axios函数放入promise中来进行尝试。它在grecaptcha.execute完成执行之前提交。
我在这里不了解什么? 我对诺言的初次体验,所以我不了解诺言如何运作吗?这不是解决此问题的最佳方法吗?完全是其他东西吗?
HTML
<head>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" defer></script>
</head>
JS
const form = document.querySelector('#subscribe');
let recaptchaToken;
const recaptchaExecute = (token) => {
recaptchaToken = token;
};
const onloadCallback = () => {
grecaptcha.render('recaptcha', {
'sitekey': 'abcexamplesitekey',
'callback': recaptchaExecute,
'size': 'invisible',
});
grecaptcha.execute();
};
form.addEventListener('submit', (e) => {
e.preventDefault();
const formResponse = document.querySelector('.js-form__error-message');
axios({
method: 'POST',
url: '/actions/newsletter/verifyRecaptcha',
data: qs.stringify({
recaptcha: recaptchaToken,
[window.csrfTokenName]: window.csrfTokenValue,
}),
config: {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
},
}).then((data) => {
if (data && data.data.success) {
formResponse.innerHTML = '';
form.submit();
} else {
formResponse.innerHTML = 'Form submission failed, please try again';
}
});
}
JS
const onloadCallback = () => {
grecaptcha.render('recaptcha', {
'sitekey': 'abcexamplesitekey',
'callback': recaptchaExecute,
'size': 'invisible',
});
};
form.addEventListener('submit', (e) => {
e.preventDefault();
const formResponse = document.querySelector('.js-form__error-message');
grecaptcha.execute().then(axios({
method: 'POST',
url: '/actions/newsletter/verifyRecaptcha',
data: qs.stringify({
recaptcha: recaptchaToken,
[window.csrfTokenName]: window.csrfTokenValue,
}),
config: {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
},
})).then((data) => {
if (data && data.data.success) {
formResponse.innerHTML = '';
form.submit();
} else {
formResponse.innerHTML = 'Form submission failed, please try again';
}
});
}
答案 0 :(得分:0)
我解决此问题的方法是将“提交”按钮更改为“哑按钮”,并使用js方法处理所有内容:
@Html.HiddenFor(model => model.ReCaptchaToken);
<input type="button"
value="Submit"
onclick="onSubmit()"
/>
Then()方法等待令牌,将其放在隐藏字段中,然后才手动提交表单:
<script>
if (typeof grecaptcha == 'object') { //undefined behind the great firewall
grecaptcha.execute('@Config.ReCaptchaSiteKey', { action: 'register' }).then(function (token) {
window.document.getElementById('ReCaptchaToken').value = token;
$('form').submit();
});
} else {
window.document.getElementById('ReCaptchaToken').value = -1;
$('form').submit();
}
</script>
注意:@ Html.HiddenFor是MVC-您可能不使用它。 $('form')是JQuery,您不一定需要-也可以使用getElementById。
答案 1 :(得分:0)
我正在使用Web服务,因为我想要一种可以在所有页面中使用的方法。 特别注意您需要返回false的事实;然后当ajax请求返回时,回发您的帖子。
<script type="text/javascript">
function CheckCaptcha()
{
grecaptcha.ready(function () {
grecaptcha.execute('<%#RecaptchaSiteKey%>', { action: 'homepage' }).then(function (token) {
$.ajax({
type: "POST",
url: "../WebServices/Captcha.asmx/CaptchaVerify",
data: JSON.stringify({ 'captchaToken' : token }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
__doPostBack('<%= RegisterButton.UniqueID%>', '');
//console.log('Passed the token successfully');
},
failure: function (response) {
//alert(response.d);
}
});
});
});
return false;
}
</script>