web-dev-qa-db-ja.com

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

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

更新:まあ、それは不可能かもしれない。誰かがreCaptchaと並行して使用する別のキャプチャライブラリを推奨できますか?同じページに2つのキャプチャを配置できるようにしたいです。

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

94
oym

同様の質問がASP=ページ( link )でこれを行うことについて尋ねられ、そこでのコンセンサスはそれでした別のキャプチャを使用する場合を除き、1つのページ上の複数のフォームでキャプチャを共有する必要があるようです。 Zend Frameworks Zend_Captchaコンポーネント( link )。

12
Steven Surowiec

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

Recaptchaのクローンを作成したり、問題を回避したりする必要はありません。 recaptchaに複数の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()を呼び出すことができます

195

シンプルで簡単:

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

これは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));
});
_

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

14
Serj Sagan

私はこの質問が古いことを知っていますが、将来誰かがそれを探す場合に備えて。 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>
7
user2709153

この回答は @ raphadkoの回答 の拡張です。

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

これは、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)これを呼び出してフィールドを反復処理し、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'});
    }
};
4
turboLoop

常に表示されるフッターに連絡先フォームがあり、アカウントの作成などのページにもキャプチャを含めることができるため、動的に次の方法で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>
3
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
surinder singh

ページのソースコードを見て、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はrecapExistfalseであるか、何らかの値を持っているかどうかを確認します。値がある場合、これはRecaptcha.destroy();を呼び出して、ロードされた古いreCaptchaを破棄し、このタブ用に再作成します。それ以外の場合、これは単にreCaptchaを作成し、_#more_info_recaptcha_box_ divに配置します。 「オファーの作成」_#product_tabs_wha_タブと同じです。

2

優れた答えの多くを構築するソリューションを次に示します。このオプションは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
kfriend

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);
1
Black

raphadko 's answer :にビットを追加するには、複数のキャプチャが(1ページに)あるため、できません(ユニバーサル)_g-recaptcha-response_ POSTパラメーターを使用します(1つのcaptchaの応答のみを保持するため)。代わりに、各captchaに対して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) + "\"}"

         });
    });
};
_

動的に変更されたすべての要素にイベント委任を適用することに注意してください( 要素の追加後のDOMの更新 を参照)。これにより、個々のcapthaの応答がそのsubmitイベントにバインドされます。

1
prograils

適切なオプションは、各フォームのレカプチャ入力をオンザフライで生成することです(2つで実行しましたが、おそらく3つ以上のフォームを実行できます)。 Recaptcha AJAX API-

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

ユーザーがフォームの1つを送信すると:

  1. 送信をインターセプトする-jQuery FormプラグインのbeforeSubmitプロパティを使用しました
  2. ページ上の既存のrecaptcha入力を破棄します-jQueryの$ .empty()メソッドとRecaptcha.destroy()を使用しました
  3. recaptcha.create()を呼び出して、特定のフォームのrecaptchaフィールドを作成します
  4. falseを返します。

次に、レプタチャに記入し、フォームを再送信できます。彼らが代わりに別のフォームを送信することに決めた場合、コードは既存のrecaptchaをチェックするため、一度にページに1つのrecaptchaしかありません。

1
siliconrockstar

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

これの利点は、html5フォーム検証をそのまま保持できることです。1つのreaptchaですが、複数のボタンインターフェイスです。 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はよりシンプルで管理しやすいと思います。

0
eatmeimadanish

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
Vanit

これを正確に行うための素敵なガイドを次に示します。

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>

PS: "grecaptcha.render"メソッドはIDを受け取ります

0
Marco