如何在一个页面上显示多个recaptcha?

oym*_*oym 96 php captcha recaptcha

我在一个页面上有2个表单.其中一种表格一直有重新显示.另一个应该在某个事件之后显示重新计算,例如最大化登录尝试.所以有时我需要2个recaptchas出现在同一页面上.这可能吗?我知道我可能只使用一个,但我的布局方式,我更希望有2.谢谢.

更新:嗯,我想这可能是不可能的.任何人都可以推荐另一个捕获库与reCaptcha并排使用吗?我真的希望能够在同一页面上有2个验证码.

更新2:如果将每个表单放在iframe中会怎样?这是一个可接受的解决方案吗?

Hüs*_*ğlı 195

使用当前版本的Recaptcha(reCAPTCHA API版本2.0),您可以在一个页面上进行多次重新访问.

没有必要克隆recaptcha,也不尝试解决问题.你只需要为recaptchas放置多个div元素,并显式地在其中渲染recaptchas.

使用google recaptcha api很容易:https:
//developers.google.com/recaptcha/docs/display#explicit_render

这是示例html代码:

<form>
    <h1>Form 1</h1>
    <div><input type="text" name="field1" placeholder="field1"></div>
    <div><input type="text" name="field2" placeholder="field2"></div>
    <div id="RecaptchaField1"></div>
    <div><input type="submit"></div>
</form>

<form>
    <h1>Form 2</h1>
    <div><input type="text" name="field3" placeholder="field3"></div>
    <div><input type="text" name="field4" placeholder="field4"></div>
    <div id="RecaptchaField2"></div>
    <div><input type="submit"></div>
</form>
Run Code Online (Sandbox Code Playgroud)

在你的javascript代码中,你必须为recaptcha定义一个回调函数:

<script type="text/javascript">
    var CaptchaCallback = function() {
        grecaptcha.render('RecaptchaField1', {'sitekey' : '6Lc_your_site_key'});
        grecaptcha.render('RecaptchaField2', {'sitekey' : '6Lc_your_site_key'});
    };
</script>
Run Code Online (Sandbox Code Playgroud)

在此之后,您的recaptcha脚本URL应如下所示:

<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
Run Code Online (Sandbox Code Playgroud)

或者不是给你的recaptcha字段提供ID,你可以给出一个类名并用你的类选择器循环这些元素并调用.render()

  • 哇!这需要一些工作,但要添加到@GeneKelly 关于`grecaptcha.getResponse(0)` 和`grecaptcha.getResponse(1)` 的注释以验证多个实例,我会补充说,索引确实必须与`grecaptcha 相对应。渲染`排序。对于这个例子,`grecaptcha.render('RecaptchaField1'...` 将使用 `grecaptcha.getResponse(0)` 进行验证,而 `grecaptcha.render('RecaptchaField2'...` 将使用 `grecaptcha.getResponse( 1)`等... (5认同)
  • @IvanJuarez作为一个新问题,这是一个很好的问题。 (2认同)
  • 对于那些想要在多个实例中使用grecaptcha.getResponse()的人,可以简单地将每个渲染引用为0,1,2等.例如,第一个实例将被引用为grecaptcha.getResponse(0). (2认同)
  • 节省我的时间它的完美解决方案 (2认同)

rap*_*dko 72

简单明了:

1)通常使用以下方法创建recaptcha字段:

<div class="g-recaptcha" data-sitekey="YOUR_KEY_HERE"></div>
Run Code Online (Sandbox Code Playgroud)

2)用这个加载脚本:

<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
Run Code Online (Sandbox Code Playgroud)

3)现在调用它迭代字段并创建recaptchas:

<script type="text/javascript">
  var CaptchaCallback = function() {
    jQuery('.g-recaptcha').each(function(index, el) {
        grecaptcha.render(el, {
            'sitekey' : jQuery(el).attr('data-sitekey')
            ,'theme' : jQuery(el).attr('data-theme')
            ,'size' : jQuery(el).attr('data-size')
            ,'tabindex' : jQuery(el).attr('data-tabindex')
            ,'callback' : jQuery(el).attr('data-callback')
            ,'expired-callback' : jQuery(el).attr('data-expired-callback')
            ,'error-callback' : jQuery(el).attr('data-error-callback')
        });
    });
  };
</script>
Run Code Online (Sandbox Code Playgroud)

  • 这是IMO的正确方式,这使得它具有动态性,因为我可以在没有定义静态ID的情况下拥有无限的实例 (4认同)
  • `data-sitekey ="YOUR_KEY_HERE"`没用,可以从div中删除(如果你需要更改密钥,更少的地方可以编辑) (3认同)
  • 其实你有一个错字.属性data-sitekey是needen,如果你有多个sitekeys,它会更加动态,为什么呢.正确的行是`grecaptcha.render(el,{'sitekey':$(el).attr('data-sitekey')});` (3认同)

Ser*_*gan 14

使用jQuery的clone()功能很容易实现.

所以你必须为recaptcha创建两个包装div.我的第一个表格的recaptcha div:

<div id="myrecap">
    <?php
        require_once('recaptchalib.php');
        $publickey = "XXXXXXXXXXX-XXXXXXXXXXX";
        echo recaptcha_get_html($publickey);
    ?>
</div>
Run Code Online (Sandbox Code Playgroud)

第二种形式的div是空的(不同的ID).所以我的只是:

<div id="myraterecap"></div>
Run Code Online (Sandbox Code Playgroud)

然后javascript很简单:

$(document).ready(function() {
    // Duplicate our reCapcha 
    $('#myraterecap').html($('#myrecap').clone(true,true));
});
Run Code Online (Sandbox Code Playgroud)

可能不需要带有true值的第二个参数clone(),但是没有伤害它...这个方法的唯一问题是如果你通过ajax提交你的表单,问题是你有两个元素有相同的名称,你必须更加聪明的方式捕获正确的元素的值(reCaptcha元素的两个id #recaptcha_response_field和#recaptcha_challenge_field,以防有人需要它们)


Ste*_*iec 12

有一个类似的问题是在ASP页面(链接)上做了这个问题,而那里的共识是不可能用recaptcha.似乎单个页面上的多个表单必须共享验证码,除非您愿意使用不同的验证码.如果您没有被锁定,那么可以查看一个好的库来查看Zend Frameworks Zend_Captcha组件(链接).它包含一些

  • **实际上可以使用reCAPTCHA**,**不可能没有JavaScript**.大多数浏览器应该支持JavaScript,默认的ReCaptcha仍然使用JavaScript,所以这个解决方案很好.[`HüseyinYağlı`的答案](http://stackoverflow.com/a/28126317/3787376)解释了解决方案.有关此解决方案的reCAPTCHA文档位于https://developers.google.com/recaptcha/docs/display#explicit_render.我不知道在没有JavaScript支持的情况下解决问题需要做些什么. (9认同)

Bla*_*ack 8

grecaptcha.getResponse()方法接受可选的“widget_id”参数,如果未指定,则默认为创建的第一个小部件。每个创建的小部件的方法都会返回一个 widget_id grecaptcha.render(),它与reCAPTCHA 容器的属性无关!id

每个 reCAPTCHA 都有自己的响应数据。您必须为 reCAPTCHA div 提供一个 ID 并将其传递给该getResponse方法:

例如

<div id="reCaptchaLogin"
     class="g-recaptcha required-entry"
     data-sitekey="<?php echo $this->helper('recaptcha')->getKey(); ?>"
     data-theme="<?php echo($this->helper('recaptcha')->getTheme()); ?>"
     style="transform:scale(0.82);-webkit-transform:scale(0.82);transform-origin:0 0;-webkit-transform-origin:0 0;">
</div>


<script type="text/javascript">
  var CaptchaCallback = function() {
    jQuery('.g-recaptcha').each(function(index, el) {
        grecaptcha.render(el, {
            'sitekey' : jQuery(el).attr('data-sitekey')
            ,'theme' : jQuery(el).attr('data-theme')
            ,'size' : jQuery(el).attr('data-size')
            ,'tabindex' : jQuery(el).attr('data-tabindex')
            ,'callback' : jQuery(el).attr('data-callback')
            ,'expired-callback' : jQuery(el).attr('data-expired-callback')
            ,'error-callback' : jQuery(el).attr('data-error-callback')
        });
    });
  };
</script>

<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
Run Code Online (Sandbox Code Playgroud)

访问响应:

var reCaptchaResponse = grecaptcha.getResponse(0);
Run Code Online (Sandbox Code Playgroud)

或者

var reCaptchaResponse = grecaptcha.getResponse(1);
Run Code Online (Sandbox Code Playgroud)

  • 哇哦,谢谢你!在官方文档中找不到这样的东西。这样您就可以拥有多个验证码,而无需显式渲染。我有一种情况,网站各处都有正常渲染,而我只需要在一个地方显式渲染 - 这解决了我的问题。 (2认同)

小智 7

我知道这个问题已经过时了,但万一有人会在将来寻找它.一页上可以有两个验证码.粉红色到文档在这里:https://developers.google.com/recaptcha/docs/display 下面的示例只是一个复制表单doc,您不必指定不同的布局.

<script type="text/javascript">
  var verifyCallback = function(response) {
    alert(response);
  };
  var widgetId1;
  var widgetId2;
  var onloadCallback = function() {
    // Renders the HTML element with id 'example1' as a reCAPTCHA widget.
    // The id of the reCAPTCHA widget is assigned to 'widgetId1'.
    widgetId1 = grecaptcha.render('example1', {
      'sitekey' : 'your_site_key',
      'theme' : 'light'
    });
    widgetId2 = grecaptcha.render(document.getElementById('example2'), {
      'sitekey' : 'your_site_key'
    });
    grecaptcha.render('example3', {
      'sitekey' : 'your_site_key',
      'callback' : verifyCallback,
      'theme' : 'dark'
    });
  };
</script>
Run Code Online (Sandbox Code Playgroud)


Van*_*Dir 5

这个答案是一个扩展@raphadko的答案.

如果您需要手动提取验证码(如在ajax请求中),您必须调用:

grecaptcha.getResponse(widget_id)
Run Code Online (Sandbox Code Playgroud)

但是如何检索widget id参数呢?

我使用CaptchaCallback的这个定义来存储每个g-recaptcha框的小部件ID(作为HTML数据属性):

var CaptchaCallback = function() {
    jQuery('.g-recaptcha').each(function(index, el) {
        var widgetId = grecaptcha.render(el, {'sitekey' : 'your code'});
        jQuery(this).attr('data-widget-id', widgetId);
    });
};
Run Code Online (Sandbox Code Playgroud)

然后我可以打电话:

grecaptcha.getResponse(jQuery('#your_recaptcha_box_id').attr('data-widget-id'));
Run Code Online (Sandbox Code Playgroud)

提取代码.

  • 嘿,谢谢你。“#your_recaptcha_box_id”是什么? (2认同)