13

The traditional way of using "I am not a robot" Recpatcha seems to be with a <form> on client-side:

<form action="post.php" method="POST">
    <div class="g-recaptcha" data-sitekey="6Lc_0f4SAAAAAF9ZA_d7Dxi9qRbPMMNW-tLSvhe6"></div>
    <button type="submit">Sign in</button>
</form>

<script src='https://www.google.com/recaptcha/api.js'></script>

Then some g-recaptcha-response will be sent to server.


However, in my code I don't use a <form> but an AJAX call instead:

$('#btn-post').click(function(e) { 
  $.ajax({
    type: "POST",
    url: "post.php",
    data: {
      action: 'post',
      text: $("#text").val(),
      ajaxMode: "true"
    },
    success: function(data) { },
    error: function(data) { } 
  }); } });

How to get the g-recaptcha-response answer with this solution?

Basj
  • 41,386
  • 99
  • 383
  • 673

3 Answers3

12

I just implemented it without using any form and submit mechanism, respectively. Thus, a pure AJAX solution.

HTML code:

<div id="recaptcha-service" class="g-recaptcha"
 data-callback="recaptchaCallback"
 data-sitekey=""></div>
<script type="text/javascript" src="https://www.google.com/recaptcha/api.js?hl=en"></script>

JavaScript code:

window.recaptchaCallback = undefined;

jQuery(document).ready(function($) {

  window.recaptchaCallback = function recaptchaCallback(response) {
    $.ajax({
      method: "POST",
      url: "http://example.com/service.ajax.php",
      data: { 'g-recaptcha-response': response },
    })
      .done(function(msg) {
        console.log(msg);
      })
      .fail(function(jqXHR, textStatus) {
        console.log(textStatus);
      });
  }

});

The point is using a callback (recaptchaCallback in this case).

You can find a more complete example at https://gist.github.com/martinburger/f9f37770c655c25d5f7b179278815084. That example uses Google's PHP implementation on the server side (https://github.com/google/recaptcha).

Martin
  • 1,875
  • 1
  • 20
  • 28
  • thank you very much, it works for me and it is a tremendously creative way but I just didn't realize why it is working!??? I did the exactly the same things just without using data-callback and relative statements and it didn't work, can you explain why we should use data-callback and ...? – TechDogLover OR kiaNasirzadeh Jul 20 '18 at 12:13
9

You use a form, interrupt the submissions of the form. Set up a form as per normal:

<form action="post.php" method="POST" id="my-form">
    <div class="g-recaptcha" data-sitekey="6Lc_0f4SAAAAAF9ZA_d7Dxi9qRbPMMNW-tLSvhe6"></div>
    <input type="text" id="text">
    <button type="submit">Sign in</button>
</form>

<script src='https://www.google.com/recaptcha/api.js'></script>

And then you use jQuery to interrupt the submission of the form and serialize it, allowing you to pass the data through Ajax:

$('#my-form').submit(function(e) {
    e.preventDefault();
    $this = $(this);
    $.ajax({
        type: "POST",
        url: "post.php",
        data: $this.serialize()
    }).done(function(data) {
    }).fail(function( jqXHR, textStatus ) {
        alert( "Request failed: " + textStatus );
    });
});

As you will have noticed I've used .done and .fail instead of success and error, this is the preferred way of handling the response.

Community
  • 1
  • 1
Styphon
  • 10,304
  • 9
  • 52
  • 86
  • 2
    So in order to not use a ``, I should use a `
    ` ?
    – Basj Jun 04 '15 at 14:51
  • Yes. Even if you're submitting a form via Ajax, you still use a form and just interrupt the submission of the form and pass it off to Ajax. Give me a sec, I'm adding an example to my answer. – Styphon Jun 04 '15 at 14:53
  • Ok. Is this a hack or normal way of doing it? Oh yes, I would be interested for an example code :) – Basj Jun 04 '15 at 14:54
  • something like `$('#myForm').on('submit', function(e) { e.preventDefault(); $.ajax({ ..., data: $(this).serialize(), ... }); } );` ? – Basj Jun 04 '15 at 14:58
  • I've updated my answer, and yes this is the standard way of doing things. – Styphon Jun 04 '15 at 15:01
  • 2
    It's called progressive enhancement. Start with the basic functionality and then add extended functionality for those who support it. If someone has JS disabled, the captcha should still work, since it will basically just fall back to the normal, good old fashioned form :-) – HaukurHaf Jun 04 '15 at 15:26
2

For answer completeness, say you wanted to just use a link you could...

<form id="g-recap">
  <div class="g-recaptcha" data-sitekey="{{ gcaptcha key }}" ></div>
</form>
<a href="/recaptchaured/path">Verify</a>

$('a').on('click',function(e) {
   e.preventDefault();
   document.location =  $(this).attr('href') + '?' + $('#g-recap').serialize()
});
zak
  • 776
  • 10
  • 10