导航后如何删除queryParams | Angular

How to remove queryParams after navigation | Angular

我正在使用 Angular 应用程序并尝试检查 CanActivate 是否 token 有效,如果有效则 return 为真。如果为真,我需要将其从 url 中删除 我试过这段代码来删除 url 参数

let url: string = this.router.url.substring(0, this.router.url.indexOf("?")); this.router.navigateByUrl(url);

却进入了死循环。如何在使用检查其有效性后删除参数?

canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    let accesstoken: string = next.queryParams.accesstoken;
    if (this.authService.IsAuthenticated) {

      let user = this.authService.GetUser();
      let CurrentDate = new Date();
      let date = CurrentDate.getFullYear() + "-" + (CurrentDate.getMonth() + 1) + "-" + CurrentDate.getDate();

      if (Date.parse(date) <= Date.parse(user.expire_date)) {
        return true;
      }
    }
      else if (!NOU(accesstoken)) { // In case current registered token is not valid, CheckAccess with new token
        // this.authService.logout();
        this.authService.checkAccess(accesstoken).subscribe(
          data => {
            if (data === true) {
              return true;
            } else {
              this.router.navigate(['/login']);
              return false;
            }

          },
          error => {

          }
        );
      }
      else {
        this.router.navigate(['/login']);
        return false;
      }

  }

`

auth.service.ts

     checkAccess(accesstoken: string) {
    let Headers = new HttpHeaders();
    Headers = Headers.append('AuthenticationToken', accesstoken);
    return this.dataService
      .post<any>(`${this.authUrl}CheckAccess.json`, null, { headers: Headers })
      .pipe(
        map(response => {
          const authenticated = response.flag;
          // login successful
          if (authenticated) {
            // you can use  JSON.parse(localStorage.getItem('user')) statement to get the user information when needed.
            const user = new User(response);
            localStorage.setItem('user', JSON.stringify(user));
            localStorage.setItem('AuthenticationToken', accesstoken);
            this.IsAuthenticated = true;
            this.authenticationSource.next(true);
            // return true to indicate successful login
            return authenticated;
          }
        }),
        catchError(conError => {
          // return false to indicate failed login response 401
          return 'Failed';
        })
      );
  }

反转-auth.guard.ts

    export class ReverseAuthGuard implements CanActivate {
  constructor(private router: Router, private authService: AuthService) { }
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean> | Promise<boolean> | boolean {

    if (this.authService.IsAuthenticated) {
      let user = this.authService.GetUser();
      let CurrentDate = new Date();
      let date = CurrentDate.getFullYear() + "-" + (CurrentDate.getMonth() + 1) + "-" + CurrentDate.getDate();

      if (Date.parse(date) > Date.parse(user.expire_date)) {
        // this.router.navigate(['/']);
        return true;
      }
      this.router.navigate(['/home']);
      return false;

    }
    else {
      return true;
    }

  }
}

app-routing.module.ts

   const routes: Routes = [
  {
    path: '',
    component: LayoutComponent,
    canActivate: [AuthGuard],
    children: [
      {
        path: 'home',
        loadChildren: './home/home.module#HomeModule',
        data: {
          title: 'Home'
        }
      },
      {
        path: '',
        redirectTo: 'home',
        pathMatch: 'full'
      }
    ]
  },
  {
    path: 'unauthorized',
    component: UnauthorizedComponent,
    canActivate: [ReverseAuthGuard],
    data: {
      title: 'Unauthorized'
    }
  },
  {
    path: 'login',
    component: LoginComponent,
    canActivate: [ReverseAuthGuard],
    data: {
      title: 'Login'
    }
  }
];

如果我们假设您的查询参数名称是 'token'

,您可以通过名称删除查询参数,传递空值
this.router.navigate(
 ['login'], {
 queryParams: {
  token: null // pass null value to token delete it 
 },
 queryParamsHandling: 'merge'
})

你会进入一个无限循环,因为你总是重定向到登录,登录将在你删除它后检查令牌,这将再次重定向。

解决方案是将您的令牌保存在会话存储中:

else if (!NOU(accesstoken)) {
     this.authService.checkAccess(accesstoken).subscribe(
       data => {
         if (data === true) {
           sessionStorage.setItem('access_token', accesstoken);
           return true;
         } else {
           const storageAccessToken = sessionStorage.getItem('access_token');
           if (storageAccessToken) {
              return true;
           }
           this.router.navigate(['/login']);
           return false;
         }
      });
 } else {
    const storageAccessToken = sessionStorage.getItem('access_token');
    if (storageAccessToken) {
       return true;
    }
    this.router.navigate(['/login']);
    return false;
 }

然后您可以毫无问题地进行重定向。要从你那里删除它Url,法塔赫在他的回答中提到了很多方法。


编辑:

在您对答案进行新编辑后,我意识到您的代码的问题是在没有令牌时重定向。所以,一个基本条件就可以解决问题:

if (this.authService.IsAuthenticated) {

  let user = this.authService.GetUser();
  let CurrentDate = new Date();
  let date = CurrentDate.getFullYear() + "-" + (CurrentDate.getMonth() + 1) + "-" + CurrentDate.getDate();

  if (Date.parse(date) <= Date.parse(user.expire_date)) {
    // check if accesstoken exists
    if (accesstoken) {
       // redirect only when exists
       this.router.navigateByUrl(window.location.pathname);
    }
    return true;
  }
}
  else if (!NOU(accesstoken)) { // In case current registered token is not valid, CheckAccess with new token
    // this.authService.logout();
    this.authService.checkAccess(accesstoken).subscribe(
      data => {
        if (data === true) {
           // check if accesstoken exists
           if (accesstoken) {
             // redirect only when exists
             this.router.navigateByUrl(window.location.pathname);
           }
          return true;
        } else {
          this.router.navigate(['/login']);
          return false;
        }

      },
      error => {

      }
    );
  }

希望能回答您的问题