Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
角度Http Request.subscribe()导致无限循环_Http_Post_Token_Jwt_Angular5 - Fatal编程技术网

角度Http Request.subscribe()导致无限循环

角度Http Request.subscribe()导致无限循环,http,post,token,jwt,angular5,Http,Post,Token,Jwt,Angular5,我想在文件auth.service.ts中编写一个函数loggedIn(),以检查本地存储中的令牌,然后在服务器端验证它。但是Typescript中的代码给出了一个无限循环。这是我的密码: auth.service.ts loggedIn(){ const token: string = localStorage.getItem('id_token'); if (token == null) { return false; } else

我想在文件
auth.service.ts
中编写一个函数
loggedIn()
,以检查本地存储中的令牌,然后在服务器端验证它。但是Typescript中的代码给出了一个无限循环。这是我的密码:

auth.service.ts

loggedIn(){

    const token: string = localStorage.getItem('id_token');    

    if (token == null) {
      return false;
    }

    else {
      const subs = this.http.post('http://localhost/url/to/myPHP.php', {"token":token})
      .map(res=>res.json()).subscribe(data=>{
        if(data.valid){
          this.valid = true;
        } else {
          this.valid = false;
        }
      },
    err=>console.log(err));

      if (this.valid){
        console.log("Valid");
        return true;
      } else {
        console.log("Invalid");
        return false;
      }
    }
  }
给定令牌:有效令牌。
结果:在Apache关闭之前,只给出“Valid”的无限console.log并返回true,无错误。
给定令牌:无效令牌
结果:在Apache关闭之前,只给出“Invalid”的infinite console.log并返回false,不出错。

我所尝试的:

    loggedIn(){
        const token: string = localStorage.getItem('id_token');

        if (token == null) {
          return false;
        }

        else {
          const subs = this.http.post('http://localhost/url/to/myPHP.php', {"token":token})
          .map(res=>res.json()).subscribe(data=>{
            if(data.valid){
              this.valid = true;
            } else {
              this.valid = false;
            }
          },
        err=>console.log(err));

          if (this.valid){
            console.log("Valid");
            console.log(this.valid);
            return true;
          } else {
            console.log("Invalid");
            console.log(this.valid);
            return false;
          }
          subs.unsubscribe();
          return true;
        }
      }
subs.unsubscribe()
确实停止了循环,但实际上它将取消订阅可观察的
,并且
.subscribe()
中的代码将不会运行。请帮忙

编辑:使用
loggedIn()

在导航栏组件中显示4次

内部
auth.guard.ts

canActivate(){
        if (this.authService.validToken){
            return true;
        } else {
            this.router.navigate(['/login']);
            return false;
        }
    }
app.module.ts中


{path:'profile',component:ProfileComponent,canActivate:[AuthGuard]}

我终于解决了这个问题
我的代码的问题是:
.subscribe()
是一个异步调用(实际计划在最后/以后执行)。这是一种情况:
ngOnInit()
位于组件文件中

loggedIn()
位于auth.service.ts文件中

  loggedIn(){

        const token: string = localStorage.getItem('id_token');    

        if (token == null) {
          return false;
        }

        else {
          const subs = this.http.post('http://localhost/url/to/myPHP.php', {"token":token})
          .map(res=>res.json()).subscribe(data=>{
            if(data.valid){
              console.log("1");
            } else {
              console.log("2");
            }

            console.log("3")
          },
        err=>console.log(err));
        }
      }
然后结果将是:
10
1
3
这意味着,您在订阅中所做的任何事情只有在您需要它之后才会更改(在许多情况下)。因此,我们需要在
subscribe()
内部执行任何需要的操作,并仅在需要时启动它。在我的例子中,如果对本地存储中的令牌应用了任何更改,我想触发它

这是我的解决方案

正如我所希望的,总是用令牌检查。我使用了
DoCheck()

verifyToken(authToken) {
    const body = {token:authToken};

    return this.http.post('http://localhost/url/to/myPHP.php',body)
    .map(res => res.json());
  }


tokenExist(): boolean {
    const token: string = localStorage.getItem('id_token');

    if (token == null) {
      return false;
    } else {
      return true;
    }
  }
内部
auth.service.ts

verifyToken(authToken) {
    const body = {token:authToken};

    return this.http.post('http://localhost/url/to/myPHP.php',body)
    .map(res => res.json());
  }


tokenExist(): boolean {
    const token: string = localStorage.getItem('id_token');

    if (token == null) {
      return false;
    } else {
      return true;
    }
  }
内部
navbar.component.ts

  ngOnInit() {
    this.curToken = localStorage.getItem('id_token');
    this.loggedIn(this.curToken);
  }

  ngDoCheck(){
    if (this.curToken != localStorage.getItem('id_token')){
      this.curToken = localStorage.getItem('id_token');
      this.loggedIn(this.curToken);
    }
  }

  loggedIn(token){
    if(this.authService.tokenExist()){
      this.authService.verifyToken(token).subscribe(data=>{
        if(data.valid){
          this.validLogin = true;
        } else {
          console.log("Invalid Token");
          this.validLogin = false;
        }
      });
    } else {
      console.log("Token Missing");
      this.validLogin = false;
    }

  }
当然,不要忘记在行中实现
DoCheck

export class NavbarComponent implements OnInit, DoCheck

您是否跟踪了调用
loggedIn()
方法的次数?您是否在模板中使用了类似于
ngIf=“loggedIn()”
的东西,每个记号都会对其进行评估?是的,我重复了5次。在
ngOnInit()
中包含“ngIf”调用一次,设置一个局部变量,并引用该变量而不是模板中的方法。具体取决于应用程序的其余部分。不过应该很容易追踪。@RobbyCornelissen谢谢你的建议,我会试试的。
export class NavbarComponent implements OnInit, DoCheck