Angular SSR:路由解析器中注入Request实例获取请求头为空
Angular SSR路由解析器中Request实例为null的解决方案
你遇到的问题核心是注入方式错误:Angular SSR中,服务器端的请求对象不是直接通过Request类注入,而是要使用@angular/platform-server提供的REQUEST令牌。另外,根注入的服务会在客户端也被实例化,这时候REQUEST不存在,所以必须做环境判断。
修复步骤:
替换注入令牌
导入REQUEST令牌和对应类型,替换原来的Request类注入:import { REQUEST } from '@angular/platform-server'; import { Request } from 'express'; // 基于Express的服务器类型,根据你的服务端框架调整修改解析器代码
调整注入逻辑,并处理Accept-Language的多值格式(比如en-US,en;q=0.9),同时区分服务器/客户端环境:@Injectable({ providedIn: 'root' }) export class DefaultlanguageResolver implements Resolve<boolean> { private translocoService = inject(TranslocoService); private navigationService = inject(NavigationService); private request = inject<Request>(REQUEST, { optional: true }); private appConfig = inject(APP_CONFIG); resolve( _route: ActivatedRouteSnapshot, _state: RouterStateSnapshot ): boolean | Observable<boolean> | Promise<boolean> { let headerLang: string | null = null; // 仅在服务器端读取请求头 if (this.request) { headerLang = this.request.headers.get('accept-language'); // 提取第一个有效语言标识,忽略权重参数 if (headerLang) { headerLang = headerLang.split(',')[0].split(';')[0]; } } // 确定目标语言:优先请求头语言,其次默认语言 const targetLang = headerLang && this.appConfig.availableLangs.includes(headerLang) ? headerLang : this.translocoService.getDefaultLang(); this.translocoService.setActiveLang(targetLang); // 重定向到带语言前缀的路由(比如/en),避免停留在空路径 this.navigationService.navigateToRoot(targetLang); return true; } }路由与导航逻辑调整
确保navigateToRoot方法接收语言参数,跳转到对应语言路由:// NavigationService示例 navigateToRoot(lang: string): void { this.router.navigate([`/${lang}`]); }
额外注意事项
- 确保你的
AppServerModule已经导入ServerModule,这是SSR提供REQUEST令牌的基础。 - 客户端导航时(比如浏览器内跳转),
REQUEST会是null,此时可以依赖Transloco的客户端语言检测逻辑(比如从localStorage读取),避免重复重定向。
内容的提问来源于stack exchange,提问作者Don
相关产品推荐
相关产品推荐

