我有一个ajax表格:
<form id="my_form">
<input type="text" id="field1" />
<input type="submit" value="submit" />
</form>
和js代码:
document.getElementById("my_form").onsubmit = function(e) {
e.preventDefault();
var xhr = new XMLHttpRequest();
//.............. send request to a server
在文档中,它假定表单是普通表单,而不是ajax。我究竟应该如何将隐形reCaptcha整合到我的ajax表单中?例如:
<form id="my_form">
<input type="text" id="field1" />
<div class="g-recaptcha" data-sitekey="12345" data-callback="????></div>
<input type="submit" value="submit" />
</form>
特别是,我应该为&#34;数据回调&#34;指定什么?处理程序?同样,在文档中,数据回调提交了一个表单,但是一个普通表单,而我的是ajax。我需要&#34;数据回调&#34;什么?难道我不应该在我的处理程序中调用recaptcha吗?怎么样?
&#34;渲染&#34;,&#34; getResponse&#34;和&#34;执行&#34;。我应该使用哪一个?从文档中不清楚。
答案 0 :(得分:27)
我同意&#34;隐形&#34; recaptcha文档不够全面。我不得不花一些时间来挖掘代码示例和#34;可见&#34;的文档。在了解如何使用它之前重新学习。
首先谈谈recaptcha API:
grecaptcha.render(htmlEl, options, inherit)
是在页面上呈现验证码HTML的JS API方法。默认情况下,recaptcha脚本将尝试查找具有class="g-recaptcha
的任何元素并尝试立即渲染,但可以通过将?render=explicit
查询参数附加到recaptcha脚本src url来覆盖此行为。当你的recaptcha .g-recaptcha
元素在加载脚本之后的某个时刻附加到DOM时,你也可能希望使用这个api按需呈现recaptcha html。这个api返回一个可以传递给其他api方法的ID值,但是如果没有传递,那些api的查找和引用第一个repcaptcha页面。
grecaptcha.getResponse(optional_id)
返回令牌。如果令牌为空字符串,则表示用户尚未经过验证,即用户尚未完成验证码质询。
grecaptcha.execute(optional_id)
api以编程方式按需触发recaptcha挑战。这个api仅适用于&#34;隐形&#34;验证码。当用户单击recaptcha模块时,会触发可见的重新访问挑战。
grecaptcha.reset(optional_id)
将重置挑战,即每次服务器无法使用recaptcha api服务器验证令牌时都必须执行此操作(因为令牌是一次性使用),但根据您的实现,您可能决定重置任何时间。
现在,我们来谈谈数据回调:
data-callback
是一个属性,您可以在其中传递全局命名空间函数的名称,即某些可作为窗口[&#39; nameOfFunction&#39;]访问的函数。每次使用您最终将传递给服务器的令牌值成功验证用户时,都会调用此回调。这是grecaptcha.getResponse()
返回的相同标记,因此从技术上讲,您根本不需要此功能。但它可以作为回调,让您知道用户已经通过验证,以防您需要更新UI或其他内容。
如果由于某种原因您不希望从窗口命名空间访问此回调,则可以使用callback
键将选项对象中的此方法传递给grecaptcha.render()
。注意:options.callback
可以采用字符串值,这相当于在HTML中传递data-callback
属性,即必须是窗口命名空间中的函数。但是options.callback
可以采用&#34;功能&#34;价值也是如此。
<强> HTML 强>
<script src="https://www.google.com/recaptcha/api.js?render=explicit&onload=onScriptLoad" async defer></script>
<强> JS 强>
window.onScriptLoad = function () {
// this callback will be called by recaptcah/api.js once its loaded. If we used
// render=explicit as param in script src, then we can explicitly render reCaptcha at this point
// element to "render" invisible captcha in
var htmlEl = document.querySelector('.g-recaptcha');
// option to captcha
var captchaOptions = {
sitekey: '6Lck',
size: 'invisible',
// tell reCaptcha which callback to notify when user is successfully verified.
// if this value is string, then it must be name of function accessible via window['nameOfFunc'],
// and passing string is equivalent to specifying data-callback='nameOfFunc', but it can be
// reference to an actual function
callback: window.onUserVerified
};
// Only for "invisible" type. if true, will read value from html-element's data-* attribute if its not passed via captchaOptions
var inheritFromDataAttr = true;
// now render
recaptchaId = window.grecaptcha.render(htmlEl, captchaOptions, inheritFromDataAttr);
};
// this is assigned from "data-callback" or render()'s "options.callback"
window.onUserVerified = function (token) {
alert('User Is verified');
console.log('token=', token);
};
// click handler for form's submit button
function onSubmitBtnClick () {
var token = window.grecaptcha.getResponse(recaptchaId);
// if no token, mean user is not validated yet
if (!token) {
// trigger validation
window.grecaptcha.execute(recaptchaId);
return;
}
var xhrData = {
'g-recaptcha-response': token
// more ajax body/data here
};
// proceed with appending more ajax call data to xhrData and then rest of ajax call process
// var xhr = new XMLHttpRequest();
// ... ... .... ... ...
}
答案 1 :(得分:-1)
您可以使用jquery轻松验证google recaptcha
<?php
$remoteip = $_SERVER['REMOTE_ADDR'];
?>
<script type="text/javascript">
function reloadRecaptcha() {
var publicKey = "your_public_key";
var div = "recap";
Recaptcha.create(publicKey,div,{theme: "white"});
return false;
}
function validate() {
var challenge = Recaptcha.get_challenge();
var response = Recaptcha.get_response();
var remoteip = "<?php echo $remoteip; ?>";
$.ajax({
type: "POST",
url: "validateRecaptcha.php",
async: false,
data: {
remoteip: remoteip,
challenge: challenge,
response: response
},
success: function(resp) {
if(resp == "true") {
document.getElementById("message").innerHTML = "Perfect!";
}
else {
document.getElementById("message").innerHTML = "Incorrect Recaptcha! Please try again!";
reloadRecaptcha();
}
}
});
return false;
}