加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Angular Universal TransferState未在客户端上加载

发布时间:2020-12-17 18:00:10 所属栏目:安全 来源:网络整理
导读:我正在尝试使用我的Angular Universal v5应用程序中的TransferState.经过大量调试后,我意识到,在服务器上,TransferState似乎正在工作,因为响应包含 script id = APP_ID / script包含适当序列化状态的标记( TransferState source). 出于某种原因,浏览器应用程
我正在尝试使用我的Angular Universal v5应用程序中的TransferState.经过大量调试后,我意识到,在服务器上,TransferState似乎正在工作,因为响应包含< script id = APP_ID>< / script>包含适当序列化状态的标记( TransferState source).

出于某种原因,浏览器应用程序尚未使用状态进行初始化.如果我将测试状态硬编码到我的应用程序的index.html文件中(通过复制和粘贴),那么我的浏览器应用程序已成功初始化为浏览器状态.我不确定出了什么问题.任何想法非常感谢!

我唯一的猜测是,当我在Chrome的检查器中观看我的应用程序加载时,看起来好像大部分元素一次被加载,然后在另一个时候勾选< script id = APP_ID>< / script>出现.这似乎暗示脚本标签是以某种方式在浏览器端生成/处理的,即使我已经检查了服务器的响应并且它包含脚本标记.但是,如果脚本标记在客户端进行某种处理,则可能在处理完成之前初始化TransferState,这就是我的应用程序未接收状态的原因.再次,任何想法都非常感谢!

这是相关代码:

app.module.ts

import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { BrowserModule,BrowserTransferStateModule } from '@angular/platform-browser';
import { environment } from '../environments/environment';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';    
import { AppRoutingModule } from './app-routing.module';
import { GraphQLModule } from './graphql.module';

@NgModule({
  imports: [
    BrowserModule.withServerTransition({ appId: 'service-work-coordination' }),BrowserTransferStateModule,AppRoutingModule,GraphQLModule,],declarations: [AppComponent],bootstrap: [AppComponent],})
export class AppModule {}

app.server.module.ts

import { NgModule } from '@angular/core';
import { ServerModule,ServerTransferStateModule } from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
  imports: [
    AppModule,ServerModule,ServerTransferStateModule,ModuleMapLoaderModule,// <-- *Important* to have lazy-loaded routes work
  ],// Since the bootstrapped component is not inherited from your
  // imported AppModule,it needs to be repeated here.
  bootstrap: [AppComponent],})
export class AppServerModule {}

graphql.module.ts

import { NgModule,APP_ID,PLATFORM_ID,Inject } from '@angular/core';
import { TransferState,makeStateKey } from '@angular/platform-browser';
import { HttpClientModule,HttpHeaders } from '@angular/common/http';
import { environment } from '../environments/environment';

// Apollo
import { ApolloModule,Apollo } from 'apollo-angular';
import { HttpLinkModule,HttpLink,HttpLinkHandler } from 'apollo-angular-link-http';
import { InMemoryCache,NormalizedCache,NormalizedCacheObject } from 'apollo-cache-inmemory';
import { setContext } from 'apollo-link-context';
import { isPlatformBrowser } from '@angular/common';

const uri = environment.uris.api.graphql;

const STATE_KEY = makeStateKey<any>('apollo.state');

@NgModule({
  imports: [
    HttpClientModule,ApolloModule,HttpLinkModule,exports: [
    HttpClientModule,]
})
export class GraphQLModule {
  private cache: InMemoryCache;
  private link: HttpLinkHandler;

  constructor(
    private apollo: Apollo,private transferState: TransferState,private httpLink: HttpLink,@Inject(PLATFORM_ID) private platformId: any,) {
    this.cache = new InMemoryCache();
    this.link = this.httpLink.create({ uri });

    console.log('transferState: ',this.transferState);

    const isBrowser = this.transferState.hasKey<NormalizedCache>(STATE_KEY);

    if (isPlatformBrowser(this.platformId)) {
      this.apollo.create({
        link: this.link,cache: this.cache,ssrForceFetchDelay: 100,});

      this.onBrowser();      
    } else {      
      this.apollo.create({
        link: this.link,ssrMode: true,});

      this.onServer();      
    }
  }

  onServer(): void {
    this.transferState.onSerialize(STATE_KEY,() => this.cache.extract());
  }

  onBrowser(): void {
    const state = this.transferState.get<NormalizedCacheObject | null>(STATE_KEY,null);

    if (state) {
      this.cache.restore(state);      
    }
  }
}

简化的服务器响应

<html>
<head>...app code...</head>
<body>
<app-root>...app code...</app-root>
<script type="text/javascript" src="inline.6ce41075b82d3dba433b.bundle.js"></script>
<script type="text/javascript" src="polyfills.37cc021a2888e752595b.bundle.js"></script>
<script type="text/javascript" src="main.1efdc21cec25daa396d1.bundle.js"></script>
<script id="service-work-coordination-state" type="application/json">{&q;apollo.state&q;:{&q;$ROOT_QUERY.person({&;q;id&;q;:&;q;074a9421-53bb-44c7-8afe-43130c723bd9&;q;})&q;:{&q;firstName&q;:&q;John&q;,&q;middleName&q;:null,&q;lastName&q;:&q;Carroll&q;,&q;primaryEmailAddress&q;:&q;:`EmailAddress::Person::Current`:`EmailAddress::Person`:`EmailAddress::Current`:`EmailAddress`:`Current` {uuid: &s;f0c4896a-27da-410b-84d3-3d66e1507a7e&s;}&q;,&q;__typename&q;:&q;Person&q;},&q;ROOT_QUERY&q;:{&q;person({&;q;id&;q;:&;q;074a9421-53bb-44c7-8afe-43130c723bd9&;q;})&q;:{&q;type&q;:&q;id&q;,&q;id&q;:&q;$ROOT_QUERY.person({&;q;id&;q;:&;q;074a9421-53bb-44c7-8afe-43130c723bd9&;q;})&q;,&q;generated&q;:true}}}}</script>
</body>
</html>

解决方法

Uggg …事实证明我已经遇到了一个已知的(谢天谢地) bug in Angular.客户端上的TransferState正在以某种方式处理/加载脚本标签时启动.为了解决这个问题,目前您需要延迟角度客户端应用程序的引导.

更新main.ts

document.addEventListener('DOMContentLoaded',() => {
  platformBrowserDynamic()
  .bootstrapModule(AppModule)
});

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读