简体   繁体   English

隐形谷歌Recaptcha和ajax形式

[英]Invisible google Recaptcha and ajax form

I have an ajax form: 我有一个ajax形式:

  <form id="my_form">
    <input type="text" id="field1" />
    <input type="submit" value="submit" />
  </form>

And js code: 和js代码:

document.getElementById("my_form").onsubmit = function(e) {
  e.preventDefault();

  var xhr = new XMLHttpRequest();
  //.............. send request to a server

In the documentation it assumes that a form is a normal form, not ajax. 在文档中,它假定表单是普通表单,而不是ajax。 How exactly should I integrate invisible reCaptcha to my ajax forms? 我究竟应该如何将隐形reCaptcha整合到我的ajax表单中? For example: 例如:

  <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>

And, in particular, what should I specify for "data-callback" handler? 而且,特别是,我应该为“数据回调”处理程序指定什么? Again, in the documentation it data-callback submits a form, but a normal form, whereas mine is ajax. 同样,在文档中,数据回调提交了一个表单,但是一个普通表单,而我的是ajax。 Do I need "data-callback" at all? 我需要“数据回调”吗? Shouldn't I instead call recaptcha inside my handler? 我不应该在我的处理程序中调用recaptcha吗? How? 怎么样?

There're "render", "getResponse" and "execute". 有“渲染”,“getResponse”和“执行”。 Which one should I use? 我应该使用哪一个? It's not clear from the documentation. 从文档中不清楚。

I agree that "invisible" recaptcha documentation is not comprehensive enough. 我同意“隐形”重新获取文件不够全面。 I had to spend some time digging thru code example and documentations of "visible" recaptcha before understanding how to work with this. 在理解如何使用它之前,我不得不花费一些时间来挖掘代码示例和“可见”recaptcha的文档。

Let talk about the recaptcha API first: 先来谈谈recaptcha API:

grecaptcha.render(htmlEl, options, inherit) is JS API method of rendering the captcha HTML on the page. grecaptcha.render(htmlEl, options, inherit)是在页面上呈现captcha HTML的JS API方法。 By default recaptcha script will try to find any element with class="g-recaptcha and try to render immediately, but this behavior can be overridden by appending ?render=explicit query param to recaptcha script src url. You also may want to render the recaptcha html on demand using this api when your recaptcha .g-recaptcha element gets attached to DOM at a point later than when script was loaded. This api returns an ID value that can be passed to other api methods, but if not passed, those api's lookup and reference first repcaptcha on page. 默认情况下,recaptcha脚本会尝试查找任何带有class="g-recaptcha元素,并尝试立即渲染,但是可以通过追加?render=explicit query param to recaptcha script src url来覆盖此行为。您也可能想要渲染当你的recaptcha .g-recaptcha元素在加载脚本之后的某个时刻附加到DOM时,使用这个api按需重新获取html。这个api返回一个ID值,可以传递给其他api方法,但如果没有传递,那些api的查找和参考第一个repcaptcha页面。

grecaptcha.getResponse(optional_id) returns the token. grecaptcha.getResponse(optional_id)返回令牌。 If token is empty string, it means user has not been validated yet ie user hasn't completed the captcha challenge. 如果token是空字符串,则表示用户尚未验证,即用户尚未完成验证码质询。

grecaptcha.execute(optional_id) api triggers the recaptcha challenge on-demand programmatically. grecaptcha.execute(optional_id) api以编程方式按需触发recaptcha challenge。 This api is only applicable to "invisible" recaptcha. 这个api仅适用于“隐形”重新捕获。 Visible recaptcha challenges are triggered when user clicks the recaptcha module. 当用户单击recaptcha模块时会触发可见的recaptcha挑战。

grecaptcha.reset(optional_id) will reset a challenge ie it must be done each time server fails to validate the token with recaptcha api server (because tokens are one time use), but depending on your implementation, you may decide to reset any time. grecaptcha.reset(optional_id)将重置一个挑战,即每次服务器无法使用recaptcha api服务器验证令牌时必须完成(因为令牌是一次性使用),但根据您的实现,您可能决定随时重置。

Now, lets talk about data-callback: 现在,让我们谈谈数据回调:

data-callback is an attribute where you can pass a name of global namespaced function, ie some function which is accessible as window['nameOfFunction']. data-callback是一个属性,您可以在其中传递全局命名空间函数的名称,即某些可作为window ['nameOfFunction']访问的函数。 This callback will get called each time user is successfully validated with a token value that you will eventually be passing to server. 每次使用您最终将传递给服务器的令牌值成功验证用户时,都会调用此回调。 This is same token that is returned by grecaptcha.getResponse() so technically you do not need this function at all. 这是grecaptcha.getResponse()返回的相同标记,因此从技术上讲,您根本不需要此功能。 But it can serve as callback to let you know user has passed verification in case you need to update UI or something. 但它可以作为回调,让您知道用户已经通过验证,以防您需要更新UI或其他东西。

If for some reason you do not want this callback to be accessible from window namespace, you can pass this method in options object with callback key to grecaptcha.render() . 如果由于某种原因您不希望从窗口命名空间访问此回调,则可以在带有callback键的options对象中将此方法传递给grecaptcha.render() NOTE: options.callback can take a string value which is equivalent to passing data-callback attribute in HTML, ie is must be a function in window namespace. 注意: options.callback可以采用字符串值,这相当于在HTML中传递data-callback属性,即必须是窗口命名空间中的函数。 But options.callback can take a "function" value as well. options.callback也可以采用“函数”值。


Now some sample code: 现在一些示例代码:

HTML HTML

<script src="https://www.google.com/recaptcha/api.js?render=explicit&onload=onScriptLoad" async defer></script>

JS 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();
  // ... ... .... ... ... 
}

You can easily validate google recaptcha's using jquery 您可以使用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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM