尝试在 Angular 17 中的 AppComponent 中触发任何 http 请求时,未定义本地存储

问题描述 投票:0回答:1

在 Docker 中运行的 Angular 17 中,我有一个独立的 AppComponent,其中包含

<router-outlet></router-outlet>

当我尝试订阅 app.component.ts 中的任何 http 请求时,应用程序不会重建并抛出错误:

_Observable {
   source: _Observable {
     source: _Observable {
       source: [_Observable],
       operator: [Function (anonymous)]
     },
     operator: [Function (anonymous)]
   },
  operator: [Function (anonymous)]
}

ERROR ReferenceError: localStorage is not defined

我如何尝试订阅http请求:

this._authService.isAdmin().subscribe()
我的服务中的 isAdmin() 方法:

  isAdmin(): Observable<any> {
    return this._http.get(LARAVEL_URL + '/api/auth/isAdmin')
  }

无论如何,任何请求都会遇到同样的问题。当此错误仍然存在时,DevTools 中的 localStorage 会变空。

我还有拦截器和 AuthGuard 来保护路由“/”处的组件。

拦截器:

export const authInterceptor: HttpInterceptorFn = (
  req: HttpRequest<any>,
  next: HttpHandlerFn
): Observable<HttpEvent<any> | any> => {
  const token = localStorage.getItem('auth_token');

  if(token) {
    const cloned = req.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`,
      },
    });
    return next(cloned);
  } else {
    return next(req);
  }
};

AuthGuard:

export class AuthGuard implements CanActivate {
  constructor(
    private authService: AuthService, 
    private router: Router
  ) {}

  canActivate(): boolean {
    if (this.authService.isAuthenticated()) {
      return true;
    } else {
      this.router.navigate(['/auth']);
      return false;
    }
  }
}

我的路线如何受到保护:

  { path: '', component: MainComponent, canActivate: [AuthGuard]},

我如何提供我的 authInterceptor:

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withInterceptors([authInterceptor]), withFetch()),
  ],
};

我尝试在另一个组件中执行http请求并将其导入到AppComponent中,但仍然出现相同的错误。

在应用程序组件上发出请求很重要,因为最终我想用 Material UI 中的 MatSideNav 包装 routerOutlet 并使我的整个应用程序包含 sideNavigation。为了切换 matSideNav 的内容,我需要 http 请求。

angular angular-httpclient
1个回答
0
投票

在服务器上

localStorage
不存在,所以我们应该检查服务器是否存在并设置默认值并避免访问
localStorage
!我们可以使用以下函数和令牌来执行此检查!

是平台浏览器

PLATFORM_ID

export const authInterceptor: HttpInterceptorFn = (
  req: HttpRequest<any>,
  next: HttpHandlerFn
): Observable<HttpEvent<any> | any> => {
  const platformId = inject(PLATFORM_ID);
  const token =  isPlatformServer(platformId) ? localStorage.getItem('auth_token') : 'some default auth token';

  if(token) {
    const cloned = req.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`,
      },
    });
    return next(cloned);
  } else {
    return next(req);
  }
};
© www.soinside.com 2019 - 2024. All rights reserved.