如何在单个页面上显示多个reCAPTCHA?

119

我在单一页上有两个表格。其中一个表格一直显示Recaptcha验证码,而另一个表格只有在特定事件发生后才会显示Recaptcha验证码,比如最大登录尝试次数超限。因此,在同一页上需要出现两个Recaptcha验证码的情况。这种情况可行吗?虽然我知道可能可以用一个Recaptcha验证码来解决,但是,基于我的布局方式,我更喜欢使用两个。谢谢。

更新:好吧,我想这可能不可能。有人能推荐与reCaptcha并排使用的其他验证码库吗?我真的很想在同一页上有两个验证码。

更新2:如果我将每个表格放在一个iframe中,这样做是否可行呢?


你不能只是简单地显示同一个两次吗? - Tyler Carter
1
我尝试过了,当我尝试复制验证码代码时,它只会显示第一个出现的验证码。 - oym
1
任何遇到新的reCAPTCHA API的人,可以通过在文档https://developers.google.com/recaptcha/docs/display#recaptcha_methods中描述的显式加载方法来实现。该文档提供了示例。 - El Yobo
3
与使用iframe相比,像Hüseyin Yağlı的回答中推荐的使用JavaScript是解决该问题的更好方式。大多数浏览器应该支持JavaScript,而默认的reCAPTCHA也已经使用了JavaScript。但我不知道如果没有JavaScript支持,需要做些什么才能解决这个问题。 - Edward
17个回答

2

查看页面源代码,我提取了reCaptcha部分并对代码进行了一些更改。以下是代码:

HTML:

<div class="tabs">
    <ul class="product-tabs">
        <li id="product_tabs_new" class="active"><a href="#">Detailed Description</a></li>
        <li id="product_tabs_what"><a href="#">Request Information</a></li>
        <li id="product_tabs_wha"><a href="#">Make Offer</a></li>
    </ul>
</div>

<div class="tab_content">
    <li class="wide">
        <div id="product_tabs_new_contents">
            <?php $_description = $this->getProduct()->getDescription(); ?>
            <?php if ($_description): ?>
                <div class="std">
                    <h2><?php echo $this->__('Details') ?></h2>
                    <?php echo $this->helper('catalog/output')->productAttribute($this->getProduct(), $_description, 'description') ?>
                </div>
            <?php endif; ?>
        </div>
    </li>

    <li class="wide">
        <label for="recaptcha">Captcha</label>
        <div id="more_info_recaptcha_box" class="input-box more_info_recaptcha_box"></div>
    </li>

    <li class="wide">
        <label for="recaptcha">Captcha</label>
        <div id="make_offer_recaptcha_box" class="input-box make_offer_recaptcha_box"></div>
    </li>
</div>

jQuery:

<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
<script type="text/javascript">
    jQuery(document).ready(function() {
        var recapExist = false;
      // Create our reCaptcha as needed
        jQuery('#product_tabs_what').click(function() {
            if(recapExist == false) {
                Recaptcha.create("<?php echo $publickey; ?>", "more_info_recaptcha_box");
                recapExist = "make_offer_recaptcha_box";
            } else if(recapExist == 'more_info_recaptcha_box') {
                Recaptcha.destroy(); // Don't really need this, but it's the proper way
                Recaptcha.create("<?php echo $publickey; ?>", "more_info_recaptcha_box");
                recapExist = "make_offer_recaptcha_box";
            }
        });
        jQuery('#product_tabs_wha').click(function() {
            if(recapExist == false) {
                Recaptcha.create("<?php echo $publickey; ?>", "make_offer_recaptcha_box");
                recapExist = "more_info_recaptcha_box";
            } else if(recapExist == 'make_offer_recaptcha_box') {
                Recaptcha.destroy(); // Don't really need this, but it's the proper way (I think :)
                Recaptcha.create("<?php echo $publickey; ?>", "make_offer_recaptcha_box");
                recapExist = "more_info_recaptcha_box";
            }
        });
    });
</script>

我在这里使用简单的JavaScript选项卡功能。因此,没有包含那段代码。

当用户单击“请求信息”(#product_tabs_what)时,JS将检查recapExist是否为false或具有某些值。如果它具有一个值,那么它将调用Recaptcha.destroy();来销毁旧的加载reCaptcha,并为此选项卡重新创建它。否则,它将只创建一个reCaptcha,并将其放置在#more_info_recaptcha_box div中。对于“提供报价”#product_tabs_wha选项卡也是如此。


2

var ReCaptchaCallback = function() {
      $('.g-recaptcha').each(function(){
      var el = $(this);
      grecaptcha.render(el.get(0), {'sitekey' : el.data("sitekey")});
      });  
        };
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=ReCaptchaCallback&render=explicit" async defer></script>


ReCaptcha 1
<div class="g-recaptcha" data-sitekey="6Lc8WQcUAAAAABQKSITdXbc6p9HISCQhZIJwm2Zw"></div>

ReCaptcha 2
<div class="g-recaptcha" data-sitekey="6Lc8WQcUAAAAABQKSITdXbc6p9HISCQhZIJwm2Zw"></div>

ReCaptcha 3
<div class="g-recaptcha" data-sitekey="6Lc8WQcUAAAAABQKSITdXbc6p9HISCQhZIJwm2Zw"></div>


2 Forms 部分在哪里? - MeSo2
抱歉,我不明白你的意思。 - surinder singh
只需将<div class="g-recaptcha" data-sitekey="your_site_key"></div>放在需要的表单/ div 中即可。 - surinder singh

1
我会使用不可见的reCAPTCHA。然后在您的按钮上使用一个标签,如“formname ='yourformname'”,以指定要提交哪个表单并隐藏提交表单输入。
这样做的好处是可以保持HTML5表单验证完整性,只需一个reCAPTCHA,但可以有多个按钮界面。只需捕获由reCAPTCHA生成的令牌密钥的“captcha”输入值即可。
<script src="https://www.google.com/recaptcha/api.js" async defer ></script>

<div class="g-recaptcha" data-sitekey="yours" data-callback="onSubmit" data-size="invisible"></div>
<script>
var formanme = ''
$('button').on('click', function () { formname = '#'+$(this).attr('formname');
    if ( $(formname)[0].checkValidity() == true) { grecaptcha.execute(); }
    else { $(formname).find('input[type="submit"]').click() }
    });

var onSubmit = function(token) {
    $(formname).append("<input type='hidden' name='captcha' value='"+token+"' />");
    $(formname).find('input[type="submit"]').click()
    };
</script>

我发现这个简单得多,更容易管理。


1
一个不错的选择是动态生成每个表单的reCAPTCHA输入框(我已经用两个做过了,但你可能可以用三个或更多表单)。我使用jQuery、jQuery验证和jQuery表单插件通过AJAX提交表单,同时使用reCAPTCHA AJAX API。

https://developers.google.com/recaptcha/docs/display#recaptcha_methods

当用户提交表单之一时:

  1. 拦截提交 - 我使用了jQuery Form插件的beforeSubmit属性
  2. 销毁页面上现有的任何recaptcha输入 - 我使用了jQuery的$.empty()方法和Recaptcha.destroy()
  3. 调用Recaptcha.create()为特定表单创建一个recaptcha字段
  4. 返回false。

然后,他们可以填写recaptcha并重新提交表单。如果他们决定提交另一个表单,那么您的代码会检查现有的recaptcha,因此您在页面上只有一个recaptcha。


1
这是一个建立在优秀答案之上的解决方案,与jQuery无关,具有动态性,不需要通过id来特定地定位元素。
1)按照正常流程添加reCAPTCHA标记:
<div class="g-recaptcha" data-sitekey="YOUR_KEY_HERE"></div>

2) 将以下内容添加到文档中。它将在支持 querySelectorAll API 的任何浏览器中工作。

<script src="https://www.google.com/recaptcha/api.js?onload=renderRecaptchas&render=explicit" async defer></script>
<script>
    window.renderRecaptchas = function() {
        var recaptchas = document.querySelectorAll('.g-recaptcha');
        for (var i = 0; i < recaptchas.length; i++) {
            grecaptcha.render(recaptchas[i], {
                sitekey: recaptchas[i].getAttribute('data-sitekey')
            });
        }
    }
</script>

0

这是可能的,只需覆盖Recaptcha Ajax回调即可。工作的jsfiddle:http://jsfiddle.net/Vanit/Qu6kn/

你甚至不需要一个代理div,因为通过覆盖DOM代码不会执行。每当您想要再次触发回调时,请调用Recaptcha.reload()。

function doSomething(challenge){
    $(':input[name=recaptcha_challenge_field]').val(challenge);
    $('img.recaptcha').attr('src', '//www.google.com/recaptcha/api/image?c='+challenge);
}

//Called on Recaptcha.reload()
Recaptcha.finish_reload = function(challenge,b,c){
    doSomething(challenge);
}

//Called on page load
Recaptcha.challenge_callback = function(){
    doSomething(RecaptchaState.challenge)
}

Recaptcha.create("YOUR_PUBLIC_KEY");

0

这里有一个非常好的指南,可以帮助您准确地完成这个任务:

http://mycodde.blogspot.com.ar/2014/12/multiple-recaptcha-demo-same-page.html

基本上,您需要向API调用添加一些参数,并手动呈现每个reCAPTCHA:

<script src="https://www.google.com/recaptcha/api.js?onload=myCallBack&render=explicit" async defer></script>
<script>
        var recaptcha1;
        var recaptcha2;
        var myCallBack = function() {
            //Render the recaptcha1 on the element with ID "recaptcha1"
            recaptcha1 = grecaptcha.render('recaptcha1', {
                'sitekey' : '6Lc_0f4SAAAAAF9ZA', //Replace this with your Site key
                'theme' : 'light'
            });

            //Render the recaptcha2 on the element with ID "recaptcha2"
            recaptcha2 = grecaptcha.render('recaptcha2', {
                'sitekey' : '6Lc_0f4SAAAAAF9ZA', //Replace this with your Site key
                'theme' : 'dark'
            });
        };
</script>

提示: "grecaptcha.render" 方法接收一个ID参数


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接