在angular2 / angular4

时间:2017-08-13 08:44:11

标签: angular typescript recaptcha

背景

我正在尝试将re-captcha集成到使用angular 4制作的单页应用程序中。我使用grecaptcha.render(elt, {sitekey : 'XXX-my-public-key'});设置了sitekey。

问题

当我打电话给grecaptcha.render()时,我无法确定是否加载了recaptcha js。因此,有时,我得到这个错误:

  

LoginComponent_Host.html:1错误ReferenceError:未定义grecaptcha

问题

在调用grecaptcha.render()之前,如何确保重新验证码已完全加载?

以下是相关的代码:

的index.html

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

login.component.html

<div #captchaDiv class="m-t"></div>

login.component.ts

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.less']
})
export class LoginComponent implements OnInit, AfterViewInit {

  @ViewChild('captchaDiv')
  captchaDiv: ElementRef;

  [...]

  ngOnInit(): void {
    grecaptcha.render(this.captchaDiv.nativeElement, {sitekey : 'XXX-my-public-key'});
  }

2 个答案:

答案 0 :(得分:1)

派对有点晚,但我认为它仍然与未来的读者有关......

我认为您缺少的是脚本标记中的asyncdefer个关键字,如下面的指南所示。

<script src="https://www.google.com/recaptcha/api.js" async defer></script>

也就是说,以下是我的完整实现,以防标签需要动态添加并自定义为特定语言(我需要)。我已按照guide on google dev portal关于如何explicitly render google recaptcha。

@Component({
   template: `<div #recaptcha ></div>`
})
export class MyComponent implements AfterViewInit {
   // Get a reference to the element which will hold the recaptcha widget
   @ViewChild('recaptcha') recaptchaContainer:ElementRef;
   // Retrieve this from your config
   captchaKey:string = 'XXX-my-public-key';

   constructor(private renderer:Renderer2) {}

   ngAfterViewInit() {
      this.initRecaptcha('en');
   }

   initRecaptcha(lang:string) {
      // Check if recaptcha global variables are set, and if so, clear them.
      // This is required in case you need to reload the recaptcha in a different language.
      if (typeof grecaptcha !== 'undefined' && typeof recaptcha !== 'undefined' && typeof  ___grecaptcha_cfg !== 'undefined') {
          grecaptcha = recaptcha = ___grecaptcha_cfg = undefined;
      }

      // Clear the content of the element, and add div to be consumed by the script
      this.recaptchaContainer.nativeElement.innerHTML = `<div class="g-recaptcha" data-sitekey="${this.captchaKey}"></div>`;

      // Append the script to load
      let script = this.renderer.createElement(this.recaptchaContainer.nativeElement, 'script');
      this.renderer.setElementAttribute(script, 'innerHTML', '');
      this.renderer.setElementAttribute(script, 'src', 'https://www.google.com/recaptcha/api.js?hl=' + lang);
      this.renderer.setElementAttribute(script, 'async', 'true');
      this.renderer.setElementAttribute(script, 'defer', 'true');
   }
}

答案 1 :(得分:-3)

尝试使用此RecaptchaModule,https://www.npmjs.com/package/ng-recaptcha

@Component({
    selector: 'my-app',
    template: `<re-captcha (resolved)="resolved($event)" siteKey="YOUR_SITE_KEY"></re-captcha>`,
}) export class MyApp {
    resolved(captchaResponse: string) {

    }
}