كيف يمكنني عرض Recaptchas متعددة على صفحة واحدة؟

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

  •  12-09-2019
  •  | 
  •  

سؤال

لدي نموذج 2 على صفحة واحدة. أحد النماذج لديه recaptcha يعرض طوال الوقت. يجب أن يعرض الآخر recaptcha فقط بعد حدث معين مثل أقصى حد محاولات تسجيل الدخول. لذلك هناك أوقات ستحتاج إلى ظهور 2 recaptchas في نفس الصفحة. هل هذا ممكن؟ أعلم أنني ربما أستخدم واحدة واحدة لكلا، ولكن الطريقة التي لدي بها التصميم، وأود أن تفضل الكثير من ذلك 2. شكرا.

تحديث: حسنا، أعتقد أنه قد لا يكون ذلك ممكنا. هل يمكن لأي شخص أن يوصي مكتبة أخرى للتقاط أن تستخدم جنبا إلى جنب مع recaptcha؟ أريد حقا أن أكون قادرا على الحصول على 2 CAPTCHAS في نفس الصفحة.

تحديث 2: ماذا لو وضع كل شكل في iframe؟ هل سيكون هذا حلا مقبولا؟

هل كانت مفيدة؟

المحلول

سئل سؤال مماثل عن القيام بذلك على صفحة ASP (حلقة الوصل) وتوافق الآراء على وجود أنه لم يكن من الممكن القيام به مع recaptcha. يبدو أن النماذج المتعددة على صفحة واحدة يجب أن تبادل كلمة التحقق، إلا إذا كنت على استعداد لاستخدام CAPTCHA مختلفة. إذا لم تكن مغلقا في Recaptcha مكتبة جيدة لإلقاء نظرة على مكون Zend_CAPTCHA (حلقة الوصل). أنه يحتوي على عدد قليل

نصائح أخرى

مع الإصدار الحالي من recaptcha (recaptcha API الإصدار 2.0)، يمكنك أن يكون لديك recaptchas متعددة على صفحة واحدة.

ليست هناك حاجة لاستنساخ recaptcha ولا تحاول الحل المشكلة. عليك فقط وضع عناصر DIV متعددة لإعادة recaptchas وتقديم recaptchas داخلها صراحة.

هذا سهل مع 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>

بعد ذلك، يجب أن يبدو عنوان URL الخاص بك recaptcha الخاص بك مثل هذا:

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

أو بدلا من إعطاء معرفات إلى حقول recaptcha الخاصة بك، يمكنك إعطاء اسم فئة وحلقة هذه العناصر مع محدد الطبقات والاتصال .رندر ()

بسيطة ومباشرة:

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>

يتم إنجاز هذا بسهولة مع JQuery's clone() وظيفة.

لذلك يجب عليك إنشاء اثنين من التفاف dives for the recaptcha. بلدي أول شكل recaptcha div:

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

النموذج الثاني DIV فارغ (معرف مختلف). لذلك الألغام هي فقط:

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

ثم جافا سكريبت بسيط للغاية:

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

ربما لا تحتاج إلى المعلمة الثانية مع true القيمة في clone(), ، لا تؤذي أنه ... المشكلة الوحيدة التي تتمتع بهذه الطريقة هي إذا قمت بتقديم النموذج الخاص بك عبر Ajax، فإن المشكلة هي أن لديك عنصرين لهما نفس الاسم ويجب عليك ذلك ذكيا أكثر قليلا الطريقة التي يمكنك التقاطها أن قيم العنصر الصحيحة (المعرفتان لعناصر recaptcha هي #recaptcha_response_field و # recaptcha_challenge_field فقط في حالة يحتاج شخص ما)

أعلم أن هذا السؤال قديم ولكن في حالة ما إذا كان أي شخص سيبحث عنه في المستقبل. من الممكن الحصول على اثنين من CAPTCHA في صفحة واحدة. الوردي إلى الوثائق هنا: 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.إجابة.

إذا كنت بحاجة إلى استخراج رمز CAPTCHA يدويا (مثل في طلبات AJAX)، عليك الاتصال:

grecaptcha.getResponse(widget_id)

ولكن كيف يمكنك استرجاع معلمة معرف القطعة؟

أنا استخدم هذا التعريف captchacallback. لتخزين معرف القطعة من كل مربع 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'));

لاستخراج الرمز.

هذه نسخة خالية من المسج للإجابة المقدمة من قبل رافادكو و اسم.

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

لدي نموذج الاتصال في تذييل الصفحة التي يعرض دائما وأيضا بعض الصفحات، مثل إنشاء حساب، يمكن أن يكون لديك captcha أيضا، لذلك انها ديناميكيا وأنا أستخدم الطريقة التالية مع jQuery:

لغة البرمجة:

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

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

جافا سكريبت

<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 وقمت بتغيير الرمز قليلا. إليك الرمز:

لغة البرمجة:

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

أنا أستخدم هنا وظيفة تبويب جافا سكريبت بسيطة. لذلك، لم يتضمن هذا الرمز.

عندما يقوم المستخدم بالنقر فوق "طلب معلومات" (#product_tabs_what) ثم JS سوف تحقق إذا recapExist يكون false أو لديه بعض القيمة. إذا كان لديه قيمة، فسوف يتصل هذا 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>

الخيار الجيد هو إنشاء مدخلات recaptcha لكل نموذج على الطاير (لقد فعلت ذلك مع اثنين ولكن ربما يمكنك القيام بثلاث أشكال أو أكثر). أنا أستخدم jQuery، jQuery valessation، و form form jQuery لنشر النموذج عبر ajax، إلى جانب recaptcha ajax API -

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

عندما يقدم المستخدم أحد النماذج:

  1. اعتراض التقديم - لقد استخدمت خاصية JQUERY FORM FORM BEFORESUBMIT
  2. تدمير أي مدخلات recaptcha الحالية على الصفحة - استخدمت طريقة jQuery's $. أمد () recaptcha.destroy ()
  3. استدعاء recaptcha.create () لإنشاء حقل recaptcha للنموذج المحدد
  4. عودة كاذبة.

ثم، يمكنهم ملء recaptcha وإعادة إرسال النموذج. إذا قرروا تقديم نموذج مختلف بدلا من ذلك، حسنا، يتحقق الرمز الخاص بك من أجل recaptchas الموجودة حتى ستحصل فقط على recaptcha واحد فقط على الصفحة في وقت واحد.

لإضافة قليلا ل رافادكوإجابة: نظرا لأن لديك متعددة CAPTCHAS (في صفحة واحدة)، لا يمكنك استخدام (عالمي) g-recaptcha-response Post Parameter (لأنه يحمل استجابة كلمة مرور واحدة فقط). بدلا من ذلك، يجب عليك استخدام grecaptcha.getResponse(opt_widget_id) دعوة لكل كلمة التحقق. إليك التعليمات البرمجية الخاصة بي (شريطة أن يكون كل كلمة التحقق داخل شكله):

لغة البرمجة:

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

جافا سكريبت:

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

         });
    });
};

لاحظ أنني أطبق وفد الحدث (انظر تحديث دوم بعد إيقاف العنصر ) لجميع العناصر المعدلة ديناميكيا. هذا يربط كل استجابة Captha الفردية على شكلها submit حدث.

إليك حلا يبني الكثير من الإجابات الممتازة. هذا الخيار هو جيس مجاني، وديناميكي، لا يتطلب منك تحديد العناصر المستهدفة حسب المعرف.

1) إضافة علامة recaptcha الخاصة بك كما كنت عادة سوف:

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

2) إضافة ما يلي إلى المستند. ستعمل في أي متصفح يدعم querysectorall 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 معرف وتمريرها إلى 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/

أنت لا تحتاج حتى إلى دس وكيل لأنه مع الكتابة فوق رمز DIM لن ينفذ. استدعاء 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/2017/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" معرف

أود استخدام recaptcha غير مرئي. ثم على زرك استخدام علامة مثل "formname =" yourformname "" لتحديد النموذج الذي سيتم تقديمه وإخفاء إدخال نموذج إرسال.

ميزة هذا هو أنها تسمح لك بالحفاظ على صحة نموذج HTML5 سليمة، recaptcha واحد، ولكن واجهات زر متعددة. مجرد التقاط قيمة إدخال "CAPTCHA" لمفتاح الرمز المميز الناتج عن 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>

أجد هذا أكثر بساطة وأسهل في الإدارة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top