我同意“不可见的”recaptcha 文档不够全面。在了解如何使用它之前,我不得不花一些时间通过代码示例和“可见”recaptcha 的文档进行挖掘。
先说一下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返回一个ID值,可以传给其他api方法,但是如果不传,那些api的查找和引用页面上的第一个recaptcha。
grecaptcha.getResponse(optional_id) 返回令牌。如果 token 为空字符串,则表示用户尚未通过验证,即用户尚未完成验证码质询。
grecaptcha.execute(optional_id) api 以编程方式按需触发recaptcha 质询。此 api 仅适用于“不可见”的 recaptcha。当用户点击recaptcha模块时,会触发可见的recaptcha挑战。
grecaptcha.reset(optional_id) 将重置挑战,即每次服务器无法使用 recaptcha api 服务器验证令牌时都必须执行此操作(因为令牌是一次性使用的),但根据您的实施,您可能决定随时重置。
现在,让我们谈谈数据回调:
data-callback 是一个属性,您可以在其中传递全局命名空间函数的名称,即某些可作为 window['nameOfFunction'] 访问的函数。每次使用您最终将传递给服务器的令牌值成功验证用户时,都会调用此回调。这与grecaptcha.getResponse() 返回的令牌相同,因此从技术上讲,您根本不需要此函数。但它可以作为回调,让您知道用户已通过验证,以防您需要更新 UI 或其他东西。
如果出于某种原因您不希望从窗口命名空间访问此回调,您可以将带有callback 键的选项对象中的此方法传递给grecaptcha.render()。注意:options.callback 可以接受一个字符串值,相当于在 HTML 中传递 data-callback 属性,即它必须是窗口命名空间中的函数。但options.callback 也可以采用“函数”值。
现在是一些示例代码:
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();
// ... ... .... ... ...
}