it-swarm.com.de

Wie zeige ich mehrere Recaptchas auf einer einzigen Seite an?

Ich habe 2 Formulare auf einer einzigen Seite. Auf einem der Formulare wird ständig ein Recaptcha angezeigt. Der andere sollte ein Recaptcha erst nach einem bestimmten Ereignis anzeigen, z. B. nach maximalem Login-Versuch. Es gibt also Zeiten, in denen ich 2 Recaptchas benötigen würde, um auf derselben Seite zu erscheinen. Ist das möglich? Ich weiß, dass ich wahrscheinlich für beide eine einzige verwenden könnte, aber so wie ich das Layout habe, würde ich es sehr bevorzugen.

Update: Nun, ich denke, es ist möglicherweise nicht möglich. Kann jemand eine andere Capture-Bibliothek empfehlen, die neben reCaptcha verwendet werden soll? Ich möchte wirklich zwei Captchas auf derselben Seite haben.

Update 2: Was ist, wenn jedes Formular in einen iframe gestellt wird? Wäre das eine akzeptable Lösung?

90
oym

Eine ähnliche Frage wurde auf einer ASP - Seite ( link ) gestellt und der Konsens bestand darin, dass Recaptcha nicht möglich war. Es scheint, dass mehrere Formulare auf einer einzigen Seite das Captcha gemeinsam verwenden müssen, es sei denn, Sie möchten ein anderes Captcha verwenden. Wenn Sie nicht an recaptcha gebunden sind, sollten Sie sich die Zend Frameworks Zend_Captcha-Komponente ( link ) ansehen. Es enthält einige 

9
Steven Surowiec

Mit der aktuellen Version von Recaptcha ( reCAPTCHA API Version 2.0 ) können Sie mehrere Recaptchas auf einer Seite haben.

Es ist nicht erforderlich, das Recaptcha zu klonen oder zu versuchen, das Problem zu umgehen. Sie müssen lediglich mehrere div-Elemente für die Recaptchas einfügen und die Recaptchas explizit darin darstellen.

Mit dem Google Recaptcha-API ist das ganz einfach:
https://developers.google.com/recaptcha/docs/display#explicit_render

Hier ist der Beispiel-HTML-Code:

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

In Ihrem Javascript-Code müssen Sie eine Rückruffunktion für Recaptcha definieren:

<script type="text/javascript">
    var CaptchaCallback = function() {
        grecaptcha.render('RecaptchaField1', {'sitekey' : '6Lc_your_site_key'});
        grecaptcha.render('RecaptchaField2', {'sitekey' : '6Lc_your_site_key'});
    };
</script>

Danach sollte Ihre Recaptcha-Skript-URL folgendermaßen aussehen:

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

Oder geben Sie Ihren Recaptcha-Feldern keine IDs, sondern geben Sie einen Klassennamen ein, und schleifen Sie diese Elemente mit dem Klassenselektor in eine Schleife.

186

Einfach und unkompliziert:

1) Erstellen Sie Ihre Recaptcha-Felder normalerweise wie folgt:

<div class="g-recaptcha" data-sitekey="YOUR_KEY_HERE"></div>

2) Laden Sie das Skript mit diesem:

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

3) Rufen Sie das jetzt auf, um die Felder zu durchlaufen und die Recaptchas zu erstellen:

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

Mit der Funktion clone() von jQuery ist dies problemlos möglich.

Sie müssen also zwei Wrapper-Divs für das Recaptcha erstellen. Mein erstes Formular ist recaptcha div:

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

Das div des zweiten Formulars ist leer (andere ID). Mein ist also nur:

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

Dann ist das Javascript ganz einfach:

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

Möglicherweise brauchen Sie den zweiten Parameter mit einem true-Wert in clone() nicht, aber es schadet nicht, ihn zu haben. Das einzige Problem bei dieser Methode ist, wenn Sie Ihr Formular über ajax absenden, das Problem ist, dass Sie zwei Elemente haben das hat den gleichen Namen und Sie müssen mich ein bisschen schlauer mit der Art und Weise machen, wie Sie die korrekten Elementwerte erfassen (die beiden IDs für reCaptcha-Elemente sind #recaptcha_response_field und #recaptcha_challenge_field, falls jemand sie benötigt)

14
Serj Sagan

Ich weiß, dass diese Frage alt ist, aber falls jemand in der Zukunft danach suchen wird. Es ist möglich, zwei Captcha-Dateien auf einer Seite zu haben. Pink zur Dokumentation ist hier: https://developers.google.com/recaptcha/docs/display .__ Das folgende Beispiel ist nur ein Formularkopierdokument und Sie müssen keine unterschiedlichen Layouts angeben.

<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

Diese Antwort ist eine Erweiterung der Antwort von @raphadko .

Wenn Sie den Captcha-Code manuell extrahieren müssen (wie in Ajax-Anforderungen), müssen Sie Folgendes anrufen:

grecaptcha.getResponse(widget_id)

Aber wie kann man den Widget-ID-Parameter abrufen?

Ich verwende diese Definition von CaptchaCallback, um die Widget-ID jeder g-recaptcha-Box (als HTML-Datenattribut) zu speichern:

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

Dann kann ich anrufen:

grecaptcha.getResponse(jQuery('#your_recaptcha_box_id').attr('data-widget-id'));

um den Code zu extrahieren.

6
VanDir

Dies ist eine JQuery-freie Version der Antwort von raphadko und noun .

1) Erstellen Sie Ihre Recaptcha-Felder normalerweise wie folgt:

<div class="g-recaptcha"></div>

2) Laden Sie das Skript mit diesem:

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

3) Rufen Sie das jetzt auf, um die Felder zu durchlaufen und die Recaptchas zu erstellen:

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

Ich habe ein Kontaktformular in der Fußzeile, das immer angezeigt wird, und auch einige Seiten, wie z. B. Konto erstellen, können Captcha haben. Es ist also dynamisch und ich verwende den nächsten Weg mit 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

Beim Betrachten des Quellcodes der Seite nahm ich den reCaptcha-Teil und änderte den Code ein wenig. Hier ist der Code:

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>

Ich verwende hier einfache Javascript-Tab-Funktionen. Also, diesen Code nicht enthalten. 

Wenn der Benutzer auf "Request Information" klickt, (#product_tabs_what), überprüft JS, ob recapExistfalse ist oder einen Wert hat. Wenn es einen Wert hat, wird Recaptcha.destroy(); aufgerufen, um das alte geladene reCaptcha zu löschen und es für diese Registerkarte neu zu erstellen. Andernfalls wird nur ein reCaptcha erstellt und in das #more_info_recaptcha_box div eingefügt. Gleich wie bei "Angebot abgeben" #product_tabs_wha.

2

Hier ist eine Lösung, die viele der hervorragenden Antworten aufbaut. Diese Option ist jQuery-frei und dynamisch. Es ist nicht erforderlich, dass Sie Elemente gezielt nach ID anvisieren. 

1) Fügen Sie Ihr reCAPTCHA-Markup wie gewohnt hinzu:

<div class="g-recaptcha" data-sitekey="YOUR_KEY_HERE"></div>

2) Fügen Sie dem Dokument Folgendes hinzu. Es funktioniert in jedem Browser, der die querySelectorAll-API unterstützt

<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

Die grecaptcha.getResponse() -Methode akzeptiert einen optionalen "widget_id" -Parameter und verwendet standardmäßig das erste Widget, das bei Nichtangabe erstellt wird. Für jedes erstellte Widget wird eine widget_id von der grecaptcha.render() -Methode zurückgegeben. Sie bezieht sich nicht auf das Attribut id des reCAPTCHA-Containers !!

Jedes reCAPTCHA hat seine eigenen Antwortdaten. Sie müssen dem reCAPTCHA div eine ID geben und diese an die Methode getResponse übergeben:

z.B.

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

Zugriffsantwort:

var reCaptchaResponse = grecaptcha.getResponse(0);

oder

var reCaptchaResponse = grecaptcha.getResponse(1);
1
Black

Um ein bisschen zu raphadko 's Antwort hinzuzufügen : da Sie mehrere Captchas (auf einer Seite) haben, können Sie nicht Verwenden Sie den (universellen) Parameter g-recaptcha-response POST) (da er nur die Antwort eines Captchas enthält) Stattdessen sollten Sie für jedes Captcha den Aufruf grecaptcha.getResponse(opt_widget_id) verwenden Mein Code (vorausgesetzt, jedes Captcha befindet sich in seinem Formular):

HTML:

<form ... />

<div id="RecaptchaField1"></div>

<div class="field">
  <input type="hidden" name="grecaptcha" id="grecaptcha" />
</div>

</form>

und

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

         });
    });
};

Beachten Sie, dass ich die Ereignisdelegierung (siehe DOM nach dem Anhängen des Elements aktualisieren ) auf alle dynamisch geänderten Elemente anwende. Dies bindet die Antwort jedes einzelnen Kapitels an das Ereignis in Form von submit.

1
prograils

Eine gute Option ist, eine Recaptcha-Eingabe für jedes Formular im laufenden Betrieb zu generieren (ich habe es mit zwei gemacht, aber Sie könnten wahrscheinlich drei oder mehr Formulare verwenden). Ich verwende jQuery, jQuery Validation und jQuery Form Plugin, um das Formular zusammen mit der Recaptcha AJAX API über AJAX zu veröffentlichen. 

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

Wenn der Benutzer eines der Formulare übergibt:

  1. fangen Sie die Übermittlung ab - Ich habe die beforeSubmit -Eigenschaft von jQuery Form Plugin verwendet
  2. vorhandene Recaptcha-Eingaben auf der Seite löschen - Ich habe die $ .empty () - Methode von jQuery und Recaptcha.destroy () verwendet.
  3. rufen Sie Recaptcha.create () auf, um ein Recaptcha-Feld für das jeweilige Formular zu erstellen
  4. falsch zurückgeben. 

Dann können sie das Recaptcha ausfüllen und das Formular erneut senden. Wenn Sie sich dafür entscheiden, stattdessen ein anderes Formular zu übermitteln, wird Ihr Code auf vorhandene Recaptchas überprüft, sodass Sie jeweils nur ein Recaptcha auf der Seite haben.

1
siliconrockstar

Ich würde unsichtbares Recaptcha verwenden. Verwenden Sie dann auf Ihrer Schaltfläche ein Tag wie "formname = 'yourformname'", um anzugeben, welches Formular gesendet werden soll, und die Eingabe eines übergebenen Formulars auszublenden. 

Der Vorteil davon ist, dass Sie die HTML-5-Formularprüfung intakt halten können, ein Recaptcha, aber mehrere Schaltflächen. Erfassen Sie einfach den Eingabewert "captcha" für den von recaptcha generierten Token-Schlüssel.

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

Ich finde das WEIT einfacher und einfacher zu handhaben. 

0
eatmeimadanish

Es ist möglich, einfach die Recaptcha Ajax-Callbacks zu überschreiben. Jsfiddle arbeiten: http://jsfiddle.net/Vanit/Qu6kn/

Sie benötigen nicht einmal ein Proxy-Div, da der DOM-Code beim Überschreiben nicht ausgeführt wird. Rufen Sie Recaptcha.reload () auf, wenn Sie die Rückrufe erneut auslösen möchten.

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

Hier ist ein netter Leitfaden für genau das:

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

Grundsätzlich fügen Sie dem api-Aufruf einige Parameter hinzu und rendern jedes Recaptcha manuell: 

<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: Die Methode "grecaptcha.render" erhält eine ID

0
Marco