隐形谷歌Recaptcha和ajax形式

时间:2017-03-17 14:13:29

标签: javascript html ajax forms recaptcha

我有一个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;。我应该使用哪一个?从文档中不清楚。

2 个答案:

答案 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;
    }