1つのページに複数の再キャプチャを表示するにはどうすればよいですか?


102

1つのページに2つのフォームがあります。フォームの1つには、常に表示される再キャプチャがあります。もう1つは、ログイン試行回数の上限などの特定のイベントの後でのみ、再キャプチャを表示する必要があります。そのため、同じページに表示するために2つの再キャプチャが必要になる場合があります。これは可能ですか?私はおそらく両方に1つを使用できることを知っていますが、私がレイアウトを持っている方法では、2を使用したいと思います。ありがとう。

アップデート:まあ、それは可能ではないかもしれませんね。誰かがreCaptchaと並べて使用する別のキャプチャライブラリを推奨できますか?同じページで2つのキャプチャを使用できるようにしたいのですが。

更新2:各フォームをiframeに配置するとどうなりますか?これは許容できる解決策でしょうか?


同じものを2回表示してみませんか?
タイラーカーター、

1
私はそれを試しました。キャプチャコードを複製しようとすると、最初に表示される
キャプチャ

新しいreCAPTCHAのAPIのこの出くわす誰もが、これはでドキュメントに例を挙げて説明明示的なロード使用することにより可能であるdevelopers.google.com/recaptcha/docs/display#recaptcha_methods
エル・ヨボを

3
IFRAMEは可能でなく、のようにJavaScriptを使用する場合と比較して、問題を解決するための悪い方法である必要があるHüseyin Yağlıの答え。ほとんどのブラウザーはJavaScriptをサポートしているはずであり、デフォルトのreCAPTCHAはとにかくJavaScriptを使用します。ただし、JavaScriptのサポートなしで問題を解決するために何をする必要があるのか​​はわかりません。
エドワード

回答:


14

ASPページ(リンク)でこれを行うことについても同様の質問があり、recaptchaで行うことは不可能であるというコンセンサスがありました。別のキャプチャを使用するつもりがない限り、1つのページの複数のフォームでキャプチャを共有する必要があるようです。recaptchaにロックされていない場合は、Zend FrameworksのZend_Captchaコンポーネント(リンク)をご覧ください。いくつか含まれています


9
実際はreCAPTCHAで可能ですが、JavaScriptなしでは不可能です。ほとんどのブラウザはJavaScriptをサポートする必要があり、デフォルトのReCaptchaはとにかくJavaScriptを使用するため、このソリューションは優れています。Hüseyin Yağlıの答えは解決策を説明しています。このソリューションのreCAPTCHAドキュメントは、developers.google.com/ recaptcha/docs/display#explicit_renderにあります。ただし、JavaScriptのサポートなしで問題を解決するために何をする必要があるのか​​はわかりません。
エドワード

実際、reCAPTCHAを使用すれば絶対に可能です
Carlos Espinoza

208

現在のバージョンのRecaptcha(reCAPTCHA APIバージョン2.0)では、1つのページに複数のrecaptchaを含めることができます。

再キャプチャのクローンを作成したり、問題を回避したりする必要はありません。reaptchaに複数の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スクリプトのURLは次のようになります。

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

または、recaptchaフィールドにIDを指定する代わりに、クラス名を指定し、クラスセレクターでこれらの要素をループして.render()を呼び出すことができます。


1
偶然にも、各フィールドのjquery検証に非表示のrecaptchaフィールドを追加する方法を知っていますか?現在、1つのrecaptchafieldでのみ機能していますが、2つのrecaptchaで機能しますか?<input type = "hidden" class = "hiddenRecaptcha required" name = "hiddenRecaptcha" id = "hiddenRecaptcha">
Ivan Juarez

2
@IvanJuarezこれは新しい質問として尋ねるのに良い質問です。
フセインYağlı

2
複数のインスタンスでgrecaptcha.getResponse()を使用したい場合は、各レンダリングを0、1、2などとして単純に参照できます。たとえば、最初のインスタンスはgrecaptcha.getResponse(0)として参照されます。
ジーンケリー

1
私の時間を完璧な解決策として
Mirza Obaid

2
うわー!これは、上のいくつかの作業をしたが、ジーン・ケリーのノートについて@に追加するgrecaptcha.getResponse(0)grecaptcha.getResponse(1)、私は、インデックスがに対応していないことを追加することになり、複数のインスタンスを検証するために grecaptcha.render順序を。この例でgrecaptcha.render('RecaptchaField1'...は、で検証され grecaptcha.getResponse(0)grecaptcha.render('RecaptchaField2'...で検証され grecaptcha.getResponse(1)ます...
codacopia

75

シンプルでわかりやすい:

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)これを呼び出してフィールドを反復処理し、recaptchaを作成します。

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

4
これはIMOの正しい方法であり、静的IDを定義せずにインスタンスを無制限にできるという点で動的になります
Greg Alexander

1
キャプチャコードを手動で抽出する必要がある場合(ajaxリクエストなど)、私の答えをください。
VanDir 2017年

私の質問を見てください。POSTパラメータは空になります。
Marcio Mazzucato 2017

3
data-sitekey="YOUR_KEY_HERE"は役に立たず、divから削除できます(キーを変更する必要がある場合、編集する場所が少なくなります)
the_nuts

3
実際には、タイプミスがあります。属性data-sitekeyが必要であり、複数のサイトキーがある場合に備えて、これをさらに動的にします。正しい行は次のようになりますgrecaptcha.render(el, {'sitekey' : $(el).attr('data-sitekey') });
Gkiokan 2017

13

これはjQueryのclone()関数で簡単に実現できます。

したがって、recaptcha用に2つのラッパーdivを作成する必要があります。私の最初のフォームのrecaptcha div:

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

2番目のフォームのdivは空です(異なるID)。だから私のものは:

<div id="myraterecap"></div>

次に、JavaScriptは非常に単純です。

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

おそらく、のtrue値を持つ2番目のパラメーターは必要ありませんが、clone()それを使用しても問題はありません...このメソッドの唯一の問題は、ajaxを介してフォームを送信する場合、問題があるのは、同じ名前で、正しい要素の値をキャプチャする方法を少し賢くする必要があります(reCaptcha要素の2つのIDは#recaptcha_response_field、誰かが必要な場合に備えて#recaptcha_challenge_fieldです)。


1つのrecaptchaインスタンスのみを更新するため、新しいチャレンジをリクエストすると問題が発生します
Ogugua Belonwu

これは機能しません...つまり、元のキャプチャ(最初の<div id = "myrecap">と呼ばれるもの)のみが更新され、その他は更新されません
Oxi

実際にOxi、あなたの懸念は私の以前のコメントで対処されました
Serj Sagan

1
あなたはおそらくそれを間違っています... jsfiddle.netのコードへのリンクはどうですか?とにかく、これを行う必要はもうありません...HüseyinYağlı回答を使用する必要があります。
Serj Sagan 2015

7

私はこの質問が古いことを知っていますが、もし誰かが将来それを探すなら。1ページに2つのキャプチャを含めることができます。ドキュメントのピンクはこちらです:https : //developers.google.com/recaptcha/docs/display 以下の例はコピーフォームのドキュメントであり、異なるレイアウトを指定する必要はありません。

<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

この回答は、@ raphadkoの回答を拡張したものです

キャプチャコードを手動で抽出する必要がある場合(ajaxリクエストのように)、次のように呼び出す必要があります。

grecaptcha.getResponse(widget_id)

しかし、ウィジェットIDパラメータをどのように取得できますか?

私は、この定義を使用CaptchaCallbackを格納するウィジェットID(HTMLデータ属性など)各G-reCAPTCHAのボックスのを:

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'));

コードを抽出します。


1
ねえ、それをありがとう。とは#your_recaptcha_box_id
Lucas Bustamante

4

私は常に表示するフッターの連絡フォームを持っています。また、アカウントの作成などの一部のページでもキャプチャを使用できるため、動的であり、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>

4

これはraphadkonounによって提供された回答の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)これを呼び出してフィールドを反復処理し、recaptchaを作成します。

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'});
    }
};

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_boxdivに配置します。「オファーする」#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つのフォームはどこにありますか?
MeSo2

ごめんなさい
スリンダーシン

ただ置く<div class="g-recaptcha" data-sitekey="your_site_key"></div>uはフォーム/ div要素で、必要な場所
シンsurinder

1

良いオプションは、その場でフォームごとにrecaptcha入力を生成することです(私は2つでそれを実行しましたが、おそらく3つ以上のフォームを実行できます)。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を返します。

次に、recapchaに記入してフォームを再送信します。代わりに別のフォームを送信することを決定した場合、コードは既存の再キャプチャをチェックするため、一度に1つのページだけが再キャプチャされます。


1

raphadkoの答えに少し追加するには:(1ページに)複数のキャプチャがあるため、(ユニバーサル)g-recaptcha-responsePOSTパラメーターを使用できません(それは1つのキャプチャの応答しか保持しないため)。代わりに、grecaptcha.getResponse(opt_widget_id)キャプチャごとにcallを使用する必要があります。これが私のコードです(各キャプチャがフォーム内にある場合):

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) + "\"}"

         });
    });
};

動的に変更されたすべての要素にイベント委任(要素追加後のDOMの更新を参照)を適用していることに注意してください。これは、フォームsubmitイベントに対する個々のキャプサの応答をバインドします。


うわぁ、これのために何時間も探していました。ありがとう!!
ブラック

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>

1

このgrecaptcha.getResponse()メソッドはオプションの「widget_id」パラメーターを受け入れ、指定されていない場合はデフォルトで作成された最初のウィジェットを使用します。widget_idはgrecaptcha.render()、作成された各ウィジェットのメソッドから返されます。これはid、reCAPTCHAコンテナの属性とは関係ありません!!

各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);

0

Recaptcha Ajaxコールバックを上書きするだけで可能です。動作するjsfiddle:http ://jsfiddle.net/Vanit/Qu6kn/

上書きするとDOMコードは実行されないため、プロキシdivも必要ありません。コールバックを再度トリガーする場合は常に、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呼び出しに追加し、各reaptchaを手動でレンダリングします。

<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:「grecaptcha.render」メソッドはIDを受け取ります


0

私は目に見えないrecaptchaを使用します。次に、ボタンで「formname = 'yourformname'」のようなタグを使用して、送信するフォームを指定し、送信フォーム入力を非表示にします。

これの利点は、html5フォームの検証をそのまま維持できることです。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>

このFARの方が管理が簡単で簡単だと思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.