Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google NoCaptcha ReCaptcha only shows up on refresh in Angular SPA

I noticed that my new ReCaptcha only showed up "sometimes" so I tried to track it down.

I have a SPA using Angular and when loading on the "/contact" page, the ReCaptcha shows up. If I load into any other page and try to navigate to the "/contact" page the ReCaptcha is not there, but if I refresh on that page, it appears again. Navigating away and returning to this page will cause it to disappear again.

My setup is similar to the following:

index.html

<html ng-app="App">
<head>
  <meta charset="UTF-8">
  <base href="/">

  <title>...</title>

  <!-- STYLES -->
  <link rel="stylesheet" type="text/css" href="libs/bootstrap/dist/css/bootstrap.min.css" />
  <link rel="stylesheet" type="text/css" href="libs/font-awesome/css/font-awesome.min.css" />
  <link rel="stylesheet" type="text/css" href="dist/css/style.min.css" />
</head>
<body>

    <!-- HEADER AND NAVBAR -->
    <header>
        <nav class="navbar navbar-default">
        ...
        </nav>
    </header>

    <!-- MAIN CONTENT AND INJECTED VIEWS -->
    <div id="main" ng-controller="MainController">
        <!-- this is where content will be injected -->
        <div ng-view></div>
    </div>

    <!-- FOOTER -->
    <footer id="footer" ng-controller="FooterController">
        <div class="text-center">
            {{ footer }}
        </div>
    </footer>

    <!-- SCRIPTS -->
    <script src="libs/angular/angular.min.js"></script>
    <script src="libs/angular-resource/angular-resource.min.js"></script>
    <script src="libs/angular-route/angular-route.min.js"></script>
    <!-- ReCaptcha -->
    <script src='https://www.google.com/recaptcha/api.js'></script>

    <!-- APP -->
    <script src="dist/js/app.min.js"></script>
</body>

</html>

contact.html

<div class="jumbotron">
    <h1 class="text-center">Contact Page</h1>

    <p class="text-center">{{ message }}</p>
    <div data-ng-controller="ContactController" id="contact-form">
        <div>
            <div ng-show="sent" class="alert alert-success">
                <strong><span class="fa fa-send"></span> Success! Message sent.</strong>
            </div>    
            <div ng-show="error" class="alert alert-danger">
                <strong><span class="fa fa-exclamation-circle"></span> Error! Please check the inputs.</strong>
            </div>
        </div>
        <form name="contactForm" role="form" method="post">
            <div class="well well-sm">
                <span class="fa fa-asterisk"></span><strong> Required Field </strong>
            </div>
            <div class="form-group">
                <label for="InputName">Your Name</label>
                <div class="input-group">
                    <input type="text" class="form-control" name="InputName" id="InputName" placeholder="Enter Name" data-ng-model="Name" required>
                    <span class="input-group-addon"><i class="fa fa-asterisk"></i></span>
                </div>
            </div>
            <div class="form-group">
                <label for="InputEmail">Your Email</label>
                <div class="input-group">
                    <input type="email" class="form-control" id="InputEmail" name="InputEmail" placeholder="Enter Email" data-ng-model="Email" required>
                    <span class="input-group-addon"><i class="fa fa-asterisk"></i></span>
                </div>
            </div>
            <div class="form-group">
                <label for="InputSubject">Subject</label>
                <div class="input-group">
                    <select class="form-control" id="InputSubject" name="InputSubject" data-ng-model="Subject" ng-options="subject.type for subject in subjects"></select>
                </div>
            </div>
            <div class="form-group">
                <label for="InputMessage">Message</label>
                <div class="input-group">
                    <textarea name="InputMessage" id="InputMessage" class="form-control" rows="5" data-ng-model="Message" required></textarea>
                    <span class="input-group-addon"><i class="fa fa-asterisk"></i></span>
                </div>
            </div>
            <div class="g-recaptcha" data-sitekey="[my_site_key]"></div>
            <button name="submit" id="submit" class="btn btn-info pull-right" data-ng-click="submit(contactForm)">Submit</button>
        </form>
    </div>
</div>

These are the only two areas that seem to affect the ReCaptcha at this point. If I can provide anymore info, please let me know.

I've looked through the Google ReCaptcha API Docs and tried to implement some of their examples but nothing seemed to work. I've also looked around SO, as well as other sites to see if anyone else was having this issue, but my search has been fruitless so far. I'll keep looking.

like image 751
McTalian Avatar asked Dec 24 '14 02:12

McTalian


2 Answers

I ended up using vc-recaptcha to get this working.

Setup is pretty simple and it is updated fairly regularly.

like image 141
McTalian Avatar answered Sep 25 '22 14:09

McTalian


This answer works for me with the new reCaptcha (I'm not a robot)

in Html (be sure to insert it within a form tag):

 <recaptcha></recaptcha>

Directive Code

angular.module('app').directive('recaptcha',['$window','$compile',function($window, $compile) {
  return {
    replace: true,
    link: function(scope, elem){
      var key = 'xxxxxxxxxxxxxxxxxxxxx';          <--<your public key
      activate();
      function activate(){
      if (angular.isDefined($window.grecaptcha)) {        
           $window.grecaptcha.render(elem[0],{
             'sitekey': key
             });           
        } else {
          activate();  **<- no good -> use some kind of promise here, just for testing**
        }
      }
    }          
  };
}]);

In old recpatche it is some kind of

  $window.grecaptcha.render(elem[0], key);   

Check API documentation for that.

Check here: http://www.codedodle.com/2014/12/google-new-recaptcha-using-javascript.html

like image 44
Cabe Skuriles Avatar answered Sep 25 '22 14:09

Cabe Skuriles