Angular项目出现ReferenceError: localStorage未定义错误求助
问题原因
localStorage is not defined错误的核心原因是你的Angular项目启用了SSR(服务端渲染),服务端运行环境中不存在浏览器专属的localStorage对象,而你的代码在服务端初始化阶段就直接调用了localStorage,导致报错。
解决方法
以下是三种实用的修复方案,确保localStorage仅在浏览器环境下执行:
方案一:直接判断浏览器环境
通过检查window对象是否存在,明确区分浏览器与服务端环境:
const siteId = this.route.snapshot.queryParamMap.get('SiteId'); // 判断当前是否为浏览器环境 const isBrowser = typeof window !== 'undefined'; if (siteId) { this.globalService.setLocalStorage('site_id', siteId); } else if (isBrowser && !localStorage.getItem("site_id")) { this.snackbarService.openSnackbar("Site id is missing", 'error'); }
同时修改globalService中的存储方法,增加环境判断:
setLocalStorage(key: string, value: string): void { if (typeof window !== 'undefined') { localStorage.setItem(key, value); } }
方案二:使用Angular官方PLATFORM_ID令牌
这是Angular推荐的环境区分方式,更规范且可维护:
- 在组件中注入
PLATFORM_ID并导入判断工具:
import { Component, Inject, OnInit } from '@angular/core'; import { PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; export class LoginComponent implements OnInit { constructor( private route: ActivatedRoute, private globalService: GlobalService, private snackbarService: SnackbarService, @Inject(PLATFORM_ID) private platformId: Object ) {} ngOnInit(): void { const siteId = this.route.snapshot.queryParamMap.get('SiteId'); const isBrowser = isPlatformBrowser(this.platformId); if (siteId) { this.globalService.setLocalStorage('site_id', siteId); } else if (isBrowser && !localStorage.getItem("site_id")) { this.snackbarService.openSnackbar("Site id is missing", 'error'); } } }
- 同步修改
globalService的存储逻辑:
import { Inject, Injectable } from '@angular/core'; import { PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; @Injectable({ providedIn: 'root' }) export class GlobalService { constructor(@Inject(PLATFORM_ID) private platformId: Object) {} setLocalStorage(key: string, value: string): void { if (isPlatformBrowser(this.platformId)) { localStorage.setItem(key, value); } } getLocalStorage(key: string): string | null { if (isPlatformBrowser(this.platformId)) { return localStorage.getItem(key); } return null; } }
方案三:延迟执行到浏览器专属生命周期
如果你的逻辑不需要在服务端执行,可将代码移至ngAfterViewInit钩子(该钩子仅在浏览器端触发):
ngAfterViewInit(): void { const siteId = this.route.snapshot.queryParamMap.get('SiteId'); if (siteId) { this.globalService.setLocalStorage('site_id', siteId); } else if (!localStorage.getItem("site_id")) { this.snackbarService.openSnackbar("Site id is missing", 'error'); } }
内容的提问来源于stack exchange,提问作者Lucian Wu
相关产品推荐
相关产品推荐

