【问题标题】:reCAPTCHA container is either not found or already contains inner elements未找到 reCAPTCHA 容器或已包含内部元素
【发布时间】:2017-12-27 02:57:42
【问题描述】:

当我尝试进行电话身份验证时,角度 4 出现错误。

我在控制台中收到此错误

reCAPTCHA 容器未找到或已包含内部元素!

我在我的网页中看不到 reCAPTCHA 容器,也无法按下它。

登录页面.ts

 import { Component, OnInit } from '@angular/core';
// tslint:disable-next-line:quotemark
import { Router } from "@angular/router";
// tslint:disable-next-line:quotemark
import { AuthService } from "../../core/auth.service";

import { ReactiveFormsModule } from '@angular/forms';
import * as firebase from 'firebase';


export class PhoneNumber {

  country: string;

  area: string;

  prefix: string;

  line: string;

  // format phone numbers as E.164

  get e164() {

    const num = this.country + this.area + this.prefix + this.line

    return `+${num}`

  }


}

@Component({
  // tslint:disable-next-line:component-selector
  selector: 'user-login',
  templateUrl: './user-login.component.html',
  styleUrls: ['./user-login.component.scss']
})
export class UserLoginComponent implements OnInit {

  // phone auth
  windowRef: any;
  phoneNumber = new PhoneNumber();
  verificationCode: string;


  user: any;
  constructor(public auth: AuthService,
              private router: Router) { 

              }


  ngOnInit() {
    this.windowRef = this.auth.windowRef
    this.windowRef.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container')
    this.windowRef.recaptchaVerifier.render()


  }

  // phone auth
   sendLoginCode() {


    const appVerifier = this.windowRef.recaptchaVerifier;


    const num = this.phoneNumber.e164;

    console.log(num);
    firebase.auth().signInWithPhoneNumber(num, appVerifier)

            .then(result => {


                this.windowRef.confirmationResult = result;


            })

            .catch( error => console.log(error) );


  }

  verifyLoginCode() {

    this.windowRef.confirmationResult

                  .confirm(this.verificationCode)

                  .then( result => {


                    this.user = result.user;


    })

    .catch( error => console.log(error, 'Incorrect code entered?'));

  }




}

html代码

    <div *ngIf="!auth.currentUser; else alreadyLoggedIn">

  <h3>Social Login</h3>


    <button (click)="signInWithGoogle()" class="button btn-social btn-google">
      <i class="fa fa-google-plus fa-lg"></i> Connect Google
    </button>

    <button (click)="signInWithGithub()" class="button btn-social btn-github">
      <i class="fa fa-github fa-lg"></i> Connect GitHub
    </button>

    <button (click)="signInWithFacebook()" class="button  btn-social btn-facebook">
      <i class="fa fa-facebook fa-lg"></i> Connect Facebook
    </button>

    <button (click)="signInWithTwitter()" class="button  btn-social btn-twitter">
      <i class="fa fa-twitter fa-lg"></i> Connect Twitter
    </button>

    <hr>

    <h3>Anonymous Login</h3>

      <button (click)="signInAnonymously()" class="button button-info">
        <i class="fa fa-user-secret fa-lg"></i> Connect Anonymously
      </button>

    <hr>


  <h1>Sign In with Your Phone Number</h1>


  <label for="phone">Phone Number</label><br>

  <input type="text" [(ngModel)]="phoneNumber.country"  class="input" placeholder="1"    maxlength="2">

  <input type="text" [(ngModel)]="phoneNumber.area"     class="input" placeholder="949"  maxlength="3">

  <input type="text" [(ngModel)]="phoneNumber.prefix"   class="input" placeholder="555"  maxlength="4">



  <div id="recaptcha-container"></div>


  <button (click)="sendLoginCode()">SMS Text Login Code</button>


  <div *ngIf="windowRef.confirmationResult">

    <hr>

    <label for="code">Enter your Verification Code Here</label><br>

    <input type="text" name="code" [(ngModel)]="verificationCode">


    <button (click)="verifyLoginCode()">Verify</button>

  </div>


</div>




<ng-template #alreadyLoggedIn>
  <p class="text-success">
    Already logged in!
  </p>
</ng-template>

身份验证服务

import { Injectable } from '@angular/core';
import { AngularFireDatabaseModule, AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
import { AngularFireAuth } from 'angularfire2/auth';
import { Router } from "@angular/router";
import * as firebase from 'firebase';


@Injectable()
export class AuthService {

  authState: any = null;

  constructor(private afAuth: AngularFireAuth,
              private db: AngularFireDatabase,
              private router:Router) {

            this.afAuth.authState.subscribe((auth) => {
              this.authState = auth
            });
          }

  // Returns true if user is logged in
  get authenticated(): boolean {
    return this.authState !== null;
  }

  // Returns current user data
  get currentUser(): any {
    return this.authenticated ? this.authState : null;
  }

  // Returns
  get currentUserObservable(): any {
    return this.afAuth.authState
  }

  // Returns current user UID
  get currentUserId(): string {
    return this.authenticated ? this.authState.uid : '';
  }


  get windowRef(){
    return window
  }




}

【问题讨论】:

标签: angular authentication angularfire2


【解决方案1】:

我在我的项目中遇到了同样的问题。我想分享我的解决方案。我希望它对某人有所帮助。

我意识到我们应该在 app.component.ts 中使用 recaptcha-container。因为我们应该在每次用户登录网站时运行这个 recaptcha。我在用户登录时使用它。 首先,我为窗口变量创建了一个服务。

import { Injectable } from '@angular/core';
@Injectable({
  providedIn: 'root'
})
export class WindowService {
 windowRef: any = window;
 constructor() { }
}

然后,我在 app.component.ts 中为 recaptcha 创建一个实例。

  recaptchaVerifier() {
   this.windowService.windowRef.recaptchaVerifier = new 
    firebase.auth.RecaptchaVerifier(
     "recaptcha-container",
     {
      size: "invisible"
     }
   );
  }
  ngOnInit(){
    this.recaptchaVerifier();
  }

app.component.html

<div id="recaptcha-container"></div>

然后,我在使用的时候得到这个实例。

loginByPhone(phone, this.windowService.windowRef.recaptchaVerifier);

您可以将您的确认结果设置为该变量(windowRef),它正在使用中。 最后你必须重置你的recaptcha,你什么时候再使用。您可以在此链接中找到 -> https://stackoverflow.com/a/45807140/9207947

【讨论】:

    【解决方案2】:

    这很可能已经晚了,仍然把它放在这里是为了任何人的利益。 我遇到了同样的问题,以下步骤解决了它:

    替换:

    &lt;div *ngIf="showRecaptchaDiv"&gt;

    到:

    &lt;div [hidden]="!showRecaptchaDiv"&gt;

    *ngIf 更改为[hidden] 对我有用。

    【讨论】:

      【解决方案3】:

      这是您的可靠来源! https://developers.google.com/recaptcha/docs/invisible

      看起来像 div &lt;div id="recaptcha-container"&gt;&lt;/div&gt; 尚未添加到您的类构造函数中的 DOM 中。

      Angular 2 也不希望您直接更改 DOM。您应该使用 ElementRef 或 ViewChild 更改 DOM!祝你好运!

      更新: 以下是如何将其添加到 dom。运行命令

      iElement.html('<div id="recaptcha-container"></div>');
      

      在 angular2 中。

      该命令将该元素添加到 dom!

      更新 #2: 尝试添加以下内容:

      首先从 npm 安装 recaptcha

      npm install angular2-recaptcha
      

      将以下内容添加到 SystemJS 配置中:

      System.config({
          map: {
              'angular2-recaptcha': 'node_modules/angular2-recaptcha'
          },
          packages: {
              app: {
                  format: 'register',
                  defaultExtension: 'js'
              },
              'angular2-recaptcha': {defaultExtension: 'js', main:'index'}
          }
      });
      

      然后添加这个模块:

      ...
      import { ReCaptchaModule } from 'angular2-recaptcha';
      ...
      
      
      ...
      @NgModule({
        imports: [...,ReCaptchaModule]
        })
      ...
      

      然后将其添加到您的 html 中:

       <re-captcha site_key="<GOOGLE_RECAPTCHA_KEY>"></re-captcha>
      

      用您的 Google reCaptcha 公钥替换 GOOGLE_RECAPTCHA_KEY

      【讨论】:

      • 对不起,我不明白你的意思,你能解释一下我该如何解决这个问题,我可以投票给你的答案并给你 50+ 分
      • 不,因为我不知道在哪里添加它,我使用类型脚本,而不是 javascript。我给了你 50+ 分,因为我很感谢你抽出时间来帮助我。
      【解决方案4】:

      尝试在您的 html 中搜索

      <script type="text/javascript" src="angular-recaptcha.js"></script>
      
       <script src="https://www.google.com/recaptcha/api.js" async defer></script>
      
      
        <div class="g-recaptcha" data-sitekey="your_site_key"></div>
      

      【讨论】:

      • data-sitekey 是什么?
      猜你喜欢
      • 2017-12-11
      • 2020-11-23
      • 2018-03-15
      • 2015-09-08
      • 2012-01-19
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多