我在一个页面上有两个表单。其中一种表格一直有重新显示。另一个应该在某个事件之后显示重新计算,例如最大化登录尝试。所以有时我需要2个recaptchas出现在同一页面上。这可能吗?我知道我可能只使用一个,但我的布局方式,我更愿意有2.谢谢。
更新:好吧我想这可能无法实现。任何人都可以推荐另一个捕获库与reCaptcha并排使用吗?我真的希望能够在同一页面上拥有2个验证码。
更新2 :如果将每个表单放在iframe中会怎样?这是一个可以接受的解决方案吗?
答案 0 :(得分:189)
使用当前版本的Recaptcha(reCAPTCHA API version 2.0),您可以在一个页面上进行多次重新学习。
没有必要克隆recaptcha,也不尝试解决问题。你只需要为recaptchas放置多个div元素,并明确地在其中渲染recaptcha。
使用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>
在您的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>
在此之后,您的recaptcha脚本网址应如下所示:
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
或者不是给你的recaptcha字段提供ID,你可以给出一个类名并用你的类选择器循环这些元素并调用.render()
答案 1 :(得分:68)
简单明了:
1)通常使用以下方法创建recaptcha字段:
<div class="g-recaptcha" data-sitekey="YOUR_KEY_HERE"></div>
2)用以下代码加载脚本:
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
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>
答案 2 :(得分:14)
这可以通过jQuery的clone()
函数轻松完成。
所以你必须为recaptcha创建两个包装div。我的第一个形式的回收div:
<div id="myrecap">
<?php
require_once('recaptchalib.php');
$publickey = "XXXXXXXXXXX-XXXXXXXXXXX";
echo recaptcha_get_html($publickey);
?>
</div>
第二种形式的div是空的(不同的ID)。所以我只是:
<div id="myraterecap"></div>
然后javascript很简单:
$(document).ready(function() {
// Duplicate our reCapcha
$('#myraterecap').html($('#myrecap').clone(true,true));
});
可能不需要在true
中使用clone()
值的第二个参数,但拥有它并不会受到伤害...此方法的唯一问题是如果您通过ajax提交表单,问题是你有两个具有相同名称的元素,你必须更加聪明地捕获正确元素的值(reCaptcha元素的两个id是{ {1}}和#recaptcha_challenge_field以防有人需要它们
答案 3 :(得分:9)
在ASP页面(link)上提出了一个类似的问题是关于这样做的问题,并且那里的共识是不可能用recaptcha。似乎单个页面上的多个表单必须共享验证码,除非您愿意使用不同的验证码。如果你没有被锁定重新访问一个好的库来看看是Zend Frameworks Zend_Captcha组件(link)。它包含一些
答案 4 :(得分: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>
答案 5 :(得分:6)
此答案是@raphadko's answer的扩展名。
如果您需要手动提取验证码(如在ajax请求中),您必须调用:
grecaptcha.getResponse(widget_id)
但是如何检索小工具ID参数?
我使用 CaptchaCallback 的这个定义来存储每个g-recaptcha框的 widget 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);
});
};
然后我可以致电:
grecaptcha.getResponse(jQuery('#your_recaptcha_box_id').attr('data-widget-id'));
提取代码。
答案 6 :(得分:4)
这是 raphadko 和名词提供的答案的无JQuery版本。
1)通常使用以下方法创建recaptcha字段:
<div class="g-recaptcha"></div>
2)用以下代码加载脚本:
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
3)现在调用它来迭代字段并创建recaptchas:
var CaptchaCallback = function() {
var captchas = document.getElementsByClassName("g-recaptcha");
for(var i = 0; i < captchas.length; i++) {
grecaptcha.render(captchas[i], {'sitekey' : 'YOUR_KEY_HERE'});
}
};
答案 7 :(得分:3)
我在页脚中总是显示联系表单,而且某些页面(如创建帐户)也可以有验证码,因此它是动态的,我正在使用jQuery的下一个方式:
HTML:
<div class="g-recaptcha" id="g-recaptcha"></div>
<div class="g-recaptcha" id="g-recaptcha-footer"></div>
的javascript
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit&hl=en"></script>
<script type="text/javascript">
var CaptchaCallback = function(){
$('.g-recaptcha').each(function(){
grecaptcha.render(this,{'sitekey' : 'your_site_key'});
})
};
</script>
答案 8 :(得分:2)
var ReCaptchaCallback = function() {
$('.g-recaptcha').each(function(){
var el = $(this);
grecaptcha.render(el.get(0), {'sitekey' : el.data("sitekey")});
});
};
&#13;
<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>
&#13;
答案 9 :(得分: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。与“Make Offer”#product_tabs_wha
标签相同。
答案 10 :(得分:1)
要向raphadko's answer添加一点:由于您有多个验证码(在一个页面上),因此您无法使用(通用)g-recaptcha-response
POST参数(因为它只包含一个验证码& #39;的回应)。相反,您应该对每个验证码使用grecaptcha.getResponse(opt_widget_id)
调用。这是我的代码(前提是每个验证码都在其表单中):
<强> HTML:强>
<form ... />
<div id="RecaptchaField1"></div>
<div class="field">
<input type="hidden" name="grecaptcha" id="grecaptcha" />
</div>
</form>
和
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
<强> JavaScript的:强>
var CaptchaCallback = function(){
var widgetId;
$('[id^=RecaptchaField]').each(function(index, el) {
widgetId = grecaptcha.render(el.id, {'sitekey' : 'your_site_key'});
$(el).closest("form").submit(function( event ) {
this.grecaptcha.value = "{\"" + index + "\" => \"" + grecaptcha.getResponse(widgetId) + "\"}"
});
});
};
请注意,我将事件委托(请参阅refresh DOM after append element)应用于所有动态修改的元素。这将对每个captha的形式submit
事件的响应进行约束。
答案 11 :(得分: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>
答案 12 :(得分:1)
一个好的选择是动态地为每个表单生成一个recaptcha输入(我已经完成了两个但你可以做三个或更多表单)。我正在使用jQuery,jQuery验证和jQuery表单插件通过AJAX发布表单,以及Recaptcha AJAX API -
https://developers.google.com/recaptcha/docs/display#recaptcha_methods
当用户提交其中一个表单时:
然后,他们可以填写recaptcha并重新提交表格。如果他们决定提交另一个表单,那么,您的代码会检查现有的重新签名,因此您一次只能在页面上进行一次重新访问。
答案 13 :(得分: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");
答案 14 :(得分:0)
这是一个很好的指南:
基本上你在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>
PS:&#34; grecaptcha.render&#34;方法接收ID
答案 15 :(得分:0)
我会使用隐形的recaptcha。然后在您的按钮上使用类似“formname ='yourformname'”的标记来指定要提交的表单并隐藏提交表单输入。
这样做的好处是它允许你保持html5表单验证完整,一个重新访问,但多个按钮接口。只需捕获recaptcha生成的令牌密钥的“验证码”输入值。
<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>
我觉得这个FAR更简单,更容易管理。
答案 16 :(得分:0)
grecaptcha.getResponse()
方法接受一个可选的“ widget_id”参数,如果未指定,则默认为创建的第一个窗口小部件。从grecaptcha.render()
方法为每个创建的窗口小部件返回一个widget_id,它与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>
访问响应:
var reCaptchaResponse = grecaptcha.getResponse(0);
或
var reCaptchaResponse = grecaptcha.getResponse(1);