首页 > 解决方案 > 在来自 ngOnInit() 内部的调用验证失败后,ngOnInit() 被一次又一次调用

问题描述

我正在开发一个简单的角度应用程序。有 login.component.ts 和 home.component.ts。

成功登录后,将调用 home.component.ts 并从 post-service 加载帖子。

不幸的是,由于某些问题,(我仍在处理)对后期服务的调用未经过身份验证。但是, home.component.ts 中的 ngInit 方法被一次又一次地调用,浏览器反复加载主页。

不知道发生了什么。

LoginComponent

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { first } from 'rxjs/operators';

import { AlertService, AuthenticationService } from '../_services';

@Component({templateUrl: 'login.component.html'})
export class LoginComponent implements OnInit {
    loginForm: FormGroup;
    loading = false;
    submitted = false;
    returnUrl: string;

    constructor(
        private formBuilder: FormBuilder,
        private route: ActivatedRoute,
        private router: Router,
        private authenticationService: AuthenticationService,
        private alertService: AlertService) {}

    ngOnInit() {
        // if(localStorage.getItem('currentUser')){
        //     console.log("User is logged in");
        //     this.router.navigate(['/home']);
        // }

        this.loginForm = this.formBuilder.group({
            email: ['', [Validators.required,   Validators.pattern(/^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,63})$/)]],
            password: ['', Validators.required]
        });

        // reset login status
        this.authenticationService.logout();

        // get return url from route parameters or default to '/'
        this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/home';
    }

    // convenience getter for easy access to form fields
    get f() { return this.loginForm.controls; }

    onSubmit() {

        this.submitted = true;

        // stop here if form is invalid
        if (this.loginForm.invalid) {
            return;
        }

        this.loading = true;
        this.authenticationService.login(this.f.email.value, this.f.password.value)
            .pipe(first())
            .subscribe(
                data => {
                    this.router.navigate(['/home']);
                },
                error => {
                    this.alertService.error(error);
                    this.loading = false;
                });
    }
}

home.component.ts

 import { Component, OnInit } from '@angular/core';
import { first } from 'rxjs/operators';
import { User } from '../_models';
import { UserService } from '../_services';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
// import { NgxSpinnerService } from 'ngx-spinner';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { error } from 'protractor';

@Component({templateUrl: 'home.component.html'})
export class HomeComponent implements OnInit {
    currentUser: User;
    users: User[] = [];
    allpost;
    notscrolly = true;
    notEmptyPost = true;



    constructor(private userService: UserService, private http: HttpClient, private router: Router,) {
        this.currentUser = JSON.parse(localStorage.getItem('currentUser'));

    }

    ngOnInit() {
        if(!this.currentUser){
          this.router.navigate(['/login']);
        }else{
         this.loadInitPost();
        console.log("Inside home component" + localStorage.getItem('currentUser'));
        }

    }

  loadInitPost() {
    const url = 'http://localhost:8080/user/questions';

    const emailId = JSON.parse(localStorage.getItem('currentUser'))['emailId'];
    console.log("email id  is  " + emailId);
    this.http.get(url,  {
      params : {
        'emailId' : JSON.parse(localStorage.getItem('currentUser'))['emailId']
      }

    }).subscribe(data => {
      // this.allpost = data;
      this.allpost = data;
    }, error => {return;});
  }

    deleteUser(id: number) {
        this.userService.delete(id).pipe(first()).subscribe(() => { 
            this.loadAllUsers() 
        });
    }

    private loadAllUsers() {
        this.userService.getAll().pipe(first()).subscribe(users => { 
            this.users = users; 
        });
    }

    onScroll() {
        if (this.notscrolly && this.notEmptyPost) {
        //   this.spinner.show();
          this.notscrolly = false;
          // this.loadNextPost();
       }
      // console.log("scrolled");
      // this.spinner.show();
      }




}
app.module.ts


import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule }    from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { Injectable } from '@angular/core';
import {
    HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
  } from '@angular/common/http';

// import { NgxSpinnerModule } from 'ngx-spinner';

// used to create fake backend
import { fakeBackendProvider } from './_helpers';

import { AppComponent }  from './app.component';
import { routing }        from './app.routing';

import { AlertComponent } from './_directives';
import { AuthGuard } from './_guards';
import { JwtInterceptor, ErrorInterceptor } from './_helpers';
import { AlertService, AuthenticationService, UserService } from './_services';
import { HomeComponent } from './home';
import { LoginComponent } from './login';
import { RegisterComponent } from './register';;
import { LogoutComponent } from './logout/logout.component'


@Injectable()
export class XhrInterceptor implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    const xhr = req.clone({
      headers: req.headers.set('X-Requested-With', 'XMLHttpRequest')
    });
    return next.handle(xhr);
  }
}

@NgModule({
    imports: [
        BrowserModule,
        ReactiveFormsModule,
        HttpClientModule,
        routing,
        InfiniteScrollModule,
        // NgxSpinnerModule
    ],
    declarations: [
        AppComponent,
        AlertComponent,
        HomeComponent,
        LoginComponent,
        RegisterComponent,
        LogoutComponent
,
        LogoutComponent    ],
    providers: [
        AuthGuard,
        AlertService,
        AuthenticationService,
        UserService,
        { provide: HTTP_INTERCEPTORS, useClass: XhrInterceptor, multi: true },
        { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }

        // provider used to create fake backend
        // fakeBackendProvider
    ],
    bootstrap: [AppComponent]
})

export class AppModule { }

但是,如果我从后端服务中删除安全性。这种重复加载停止。

堆栈闪电战https://stackblitz.com/github/bjs007/angular

标签: angular

解决方案


您有一个ErrorInterceptor在出现 401 时会重新加载的内容。您说后期服务中存在一些身份验证问题,看看它是否返回 401,然后您ErrorInterceptor会导致页面一次又一次地重新加载。

 if (err.status === 401) {
            // auto logout if 401 response returned from api
            // this.authenticationService.logout();
            location.reload(true);
 }

当您收到 401 时,您可以导航到登录页面this.router.navigate(['/login']);


推荐阅读