Angular2页面刷新时如何保持Token不丢失?
解决Angular页面刷新后Token丢失的问题
看起来你遇到的核心问题是页面刷新后Angular服务的内存变量会被重置——虽然你已经把Token存在localStorage里了,但没有在应用初始化时主动从localStorage中读取并同步到各个服务和组件中,导致刷新后服务里的Token变成空值。
下面结合你的代码给出具体的修改方案:
1. 修复Token传递服务(DataService)
让服务初始化时自动从localStorage读取Token,确保刷新后能直接拿到值:
import { Injectable } from '@angular/core'; @Injectable() export class DataService { public token: string; constructor() { // 应用启动时自动从localStorage加载Token this.token = localStorage.getItem("token") || ''; } setToken(token: any) { this.token = token; // 设置Token时同步更新localStorage,保证持久化 localStorage.setItem("token", token); } }
2. 修复API请求服务(ParkingService)
在服务初始化时,从localStorage获取Token并同步到BehaviorSubject中,这样刷新后API请求能正常拿到Token:
import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable, throwError as observableThrowError } from 'rxjs'; import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; import { catchError } from 'rxjs/operators'; import { Router } from '@angular/router'; import { DataService } from './data.service'; @Injectable() export class ParkingService { public userToken$: BehaviorSubject<string> = new BehaviorSubject<string>(null); public token: string; currenttoken = this.userToken$.asObservable(); constructor( private httpclient: HttpClient, private root: Router, private dataservice: DataService ) { // 初始化时优先从localStorage取Token,没有的话再用DataService的 const savedToken = localStorage.getItem("token") || this.dataservice.token; if (savedToken) { this.userToken$.next(savedToken); this.token = savedToken; this.dataservice.setToken(savedToken); // 同步到DataService } this.userToken$.subscribe(token => { this.token = token; console.log(this.token); }); } setUserToken(token: string) { this.userToken$.next(token); this.dataservice.setToken(token); // 同步更新DataService和localStorage } getparkingDetails(): Observable<any> { console.log(this.token); const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': 'Bearer: ' + this.token, }), }; return this.httpclient.get<any>("https://socialpark.iti.gr:8005/parking_sites/management", httpOptions) .pipe(catchError(this.errorHandler)); } // 补充完整的错误处理方法 private errorHandler(error: HttpErrorResponse) { window.alert("Παρακαλώ δώστε έγκυρο token για το χώρο στάθμευσης"); console.error(error); this.root.navigate(['/pages/dashboard']); return observableThrowError(error.message || 'Server error'); } }
3. 修复主页面组件(DashboardComponent)
在组件初始化时,先检查localStorage里的Token,如果没有就直接跳回首页,避免无效的API请求:
ngOnInit() { // 先从localStorage获取Token const savedToken = localStorage.getItem("token"); if (!savedToken) { // 没有Token直接跳回首页 window.alert("Παρακαλώ δώστε έγκυρο token για το χώρο στάθμευσης"); this.root.navigate(['/']); // 这里替换成你的首页路由 return; } // 同步Token到各个服务 this.token = savedToken; this.dataservice.setToken(savedToken); this.parkingService.setUserToken(savedToken); // 再调用API获取数据 this.parkingService.getparkingDetails().subscribe( data => { this.parkingid = data._id; this.getdata = JSON.parse(data.spaces_occupied_current_slot.conventional); this.allspots = JSON.parse(data.space_total.conventional); this.getdatadis = JSON.parse(data.spaces_occupied_current_slot.disabled); this.allspotsdis = JSON.parse(data.space_total.disabled); }, error => { // 错误处理已经在服务中完成,这里可以不用重复写 } ); }
额外优化建议
- 全局Token初始化:可以在
AppComponent的ngOnInit中做一次Token的全局同步,确保所有组件和服务启动时都能拿到最新的Token - Token过期处理:在API请求返回401(未授权)时,自动清除
localStorage中的Token并跳回首页,提升用户体验 - 避免重复存储:始终以
localStorage作为Token的唯一持久化源,服务和组件中的Token都从这里读取,保证数据一致性
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

