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

StackOverflow https://stackoverflow.com/questions/1241947

  •  12-09-2019
  •  | 
  •  

質問

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

アップデート: まあそれは無理かもしれないけど。reCaptcha と並行して使用する別のキャプチャ ライブラリを推奨できる人はいますか?同じページに 2 つのキャプチャを表示できるようにしたいと考えています。

アップデート 2: 各フォームを iframe に配置したらどうなるでしょうか?これは受け入れられる解決策でしょうか?

役に立ちましたか?

解決

ASP ページでこれを行うことについて同様の質問がありました (リンク)そして、そこでのコンセンサスは、再キャプチャでは実行できないということでした。別のキャプチャを使用する場合を除き、単一ページ上の複数のフォームでキャプチャを共有する必要があるようです。recaptcha に縛られていない場合は、Zend Frameworks Zend_Captcha コンポーネント (リンク)。いくつか含まれています

他のヒント

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

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() を呼び出すこともできます。

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

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

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

これはjQueryを使えば簡単に実現できます。 clone() 関数。

したがって、再キャプチャ用に 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));
});

おそらく 2 番目のパラメータは必要ありません。 true の値 clone(), でも、持っていて損はありません…。この方法の唯一の問題は、ajax 経由でフォームを送信する場合、同じ名前の要素が 2 つあることです。その正しい要素の値 (2 つの ID) を取得する方法をもう少し賢くする必要があります。 reCaptcha 要素の場合は、 #recaptcha_response_field 誰かが必要とする場合に備えて #recaptcha_challenge_field と #recaptcha_challenge_field を追加してください)

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

この回答は次の拡張です @raphadkoさんの答え.

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

grecaptcha.getResponse(widget_id)

しかし、ウィジェット ID パラメーターはどうやって取得できるのでしょうか?

私はこの定義を使用します キャプチャコールバック を保管する ウィジェットID 各 g-recaptcha ボックスの (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'));

コードを抽出します。

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

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

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

ページのソースコードを見て、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 部「オファーをする」と同じ #product_tabs_wha タブ。

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 つで実行しましたが、おそらく 3 つ以上のフォームを実行できるでしょう)。jQuery、jQuery 検証、jQuery フォーム プラグインを使用して、Recaptcha AJAX API とともに AJAX 経由でフォームを投稿しています。

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

ユーザーがいずれかのフォームを送信すると、次のようになります。

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

その後、再キャプチャに記入してフォームを再送信できます。代わりに別のフォームを送信することにした場合、コードは既存の再キャプチャをチェックするため、ページ上には一度に 1 つの再キャプチャのみが表示されます。

少し付け加えると、 ラファドコさんの答え:(1 ページに) 複数のキャプチャがあるため、(ユニバーサル) を使用することはできません。 g-recaptcha-response POST パラメータ (キャプチャの応答を 1 つだけ保持するため)。代わりに、使用する必要があります 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 を更新する ) 動的に変更されるすべての要素に適用されます。これにより、個々のキャプサの応答がその形式にバインドされます。 submit イベント。

ここでは、多くの優れた回答を基にして構築されたソリューションを紹介します。このオプションは 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>

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

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

まさにそれを行うための優れたガイドは次のとおりです。

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を受け取ります

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

この利点は、HTML5 フォーム検証をそのまま維持できること、再キャプチャは 1 つですが、複数のボタン インターフェイスを使用できることです。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 の方がシンプルで管理しやすいと思います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top