Angular Universal SSR启动报localStorage未定义错误如何解决?
Angular Universal SSR localStorage不存在报错解决方案
根本原因
Angular Universal 服务端渲染阶段运行在 Node.js 环境,该环境没有浏览器提供的 localStorage 全局 API。报错代码位于 app-routing.module.ts 的路由配置中,直接在 redirectTo 属性中调用了 localStorage.getItem(),该逻辑在服务端初始化模块时就会执行,找不到对应API就会抛出 ReferenceError。
修复方案
方案1:区分运行环境调用,适配服务端/浏览器端
Angular 官方提供了 isPlatformBrowser 工具判断当前运行环境,同时需要将原本写死在 redirectTo 中的逻辑迁移到路由守卫中,避免模块初始化阶段就执行浏览器端逻辑:
- 新增路由守卫处理重定向逻辑
import { Inject, Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router'; import { PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; @Injectable({ providedIn: 'root' }) export class CountryRedirectGuard implements CanActivate { constructor( private router: Router, @Inject(PLATFORM_ID) private platformId: Object ) {} canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): boolean | UrlTree { // 仅浏览器端读取localStorage if (isPlatformBrowser(this.platformId)) { const countryCode = localStorage.getItem('countryCode') || 'my'; return this.router.parseUrl(`/${countryCode}`); } // 服务端返回默认重定向路径 return this.router.parseUrl('/my'); } }
- 修改路由配置,替换原有直接写redirectTo的规则
const routes: Routes = [ { path: '', canActivate: [CountryRedirectGuard], pathMatch: 'full' }, // 其余原有路由保持不变 ];
方案2:服务端模拟localStorage(改动量最小)
如果不想修改现有业务逻辑,可以在服务端启动文件 server.ts 顶部添加模拟的localStorage对象:
// server.ts 最顶部添加如下代码 (global as any).localStorage = { getItem: (key: string) => { // 可根据业务需求调整默认返回值,也可以结合请求Cookie/头信息返回对应值 return 'my'; }, setItem: (key: string, value: string) => {}, removeItem: (key: string) => {}, clear: () => {} };
注意事项
所有调用浏览器独有API(window/document/localStorage等)的逻辑,都需要做运行环境判断,或者在服务端做兼容模拟,避免在模块初始化、组件构造等服务端会执行的阶段直接调用。
内容的提问来源于stack exchange,提问作者Bhavya
相关产品推荐
相关产品推荐

