Spartacus 3.4多站点SSR状态传递异常,跨站点返回旧站点数据
Spartacus 2.0升3.4版本多站点跨域状态复用问题解决方案
问题根因
Spartacus 3.x版本默认启用的SSR状态转移(State Transfer)机制,在多站点共用同一SSR服务/NGINX反向代理时,未针对站点维度做状态隔离,导致服务端返回上一次请求的站点状态,客户端优先读取storage存储的旧站点配置,不会主动根据当前域名重置上下文参数。
修复步骤
1. 修正SSR侧缓存隔离规则
- 禁用SSR层的全局状态缓存,改为按站点域名+站点上下文维度生成缓存key,核心修改
NgExpressEngine配置:
ngExpressEngine({ bootstrap: AppServerModule, providers: [ { provide: 'SERVER_REQUEST_ORIGIN', useFactory: (req: Request) => req.headers.host, deps: [REQUEST] } ], // 缓存key必须携带站点唯一标识 cache: { getKey: (req: Request) => `${req.headers.host}|${req.originalUrl}` } })
- 若NGINX层配置了静态页面缓存,调整缓存key规则加入
$host变量,示例配置:
# 原错误配置(缺少host维度) # proxy_cache_key $scheme$request_uri; # 修正后配置 proxy_cache_key $host$scheme$request_uri;
2. 调整客户端站点上下文加载优先级
修改SiteContextConfig配置,将当前域名匹配的站点配置优先级提升至高于storage存储的配置:
// app.module.ts 新增配置 providers: [ { provide: SITE_CONTEXT_CONFIG, useValue: { context: { // 按实际站点域名配置匹配规则,优先从域名提取站点标识 urlMatchingPatterns: [ '^https?://(?<site>au|nz)\\.yourdomain\\.com' ], parameters: { site: { // 禁用storage中存储的site参数优先读取逻辑 persistence: 'none' }, currency: { persistence: 'session' } } } } } ]
3. 新增应用初始化钩子覆盖旧转移状态
新增初始化逻辑,在状态转移数据加载前先匹配当前域名对应的站点配置,覆盖转移状态中携带的旧站点数据:
export function siteContextInitializer( siteContextService: SiteContextService, transferState: TransferState ) { return () => { // 先根据当前域名匹配站点信息 const currentSite = matchSiteByHost(window.location.host); if (currentSite) { // 覆盖transfer state中存储的旧站点ID transferState.set(MAKE_STATE_KEY('siteId'), currentSite.id); siteContextService.setActiveSite(currentSite.id); } }; } // 加入providers配置 { provide: APP_INITIALIZER, useFactory: siteContextInitializer, deps: [SiteContextService, TransferState], multi: true }
4. 验证修复效果
- 清理浏览器storage后依次访问两个站点,验证跨站点切换时storage中站点ID、货币自动同步为当前站点配置,无需手动刷新
- 禁用JS后直接访问两个站点页面源码,确认返回的
transfer-state脚本中携带的站点ID与当前访问域名匹配,无跨站点复用情况
注意:若SSR服务为多实例部署,需确保所有实例的缓存规则同步更新,避免部分实例返回旧缓存数据。
内容的提问来源于stack exchange,提问作者Anuj Sharma
相关产品推荐
相关产品推荐

