Angular NgRx/Store 的通用 Http 错误

Angular Universal Http Errors with NgRx/Store

我正在尝试使用 Angular Universal 完成服务器端渲染并预渲染它:

Server.ts

import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import {renderModuleFactory} from '@angular/platform-server';
import * as express from 'express';
import { readFileSync } from 'fs';
import { enableProdMode } from '@angular/core';

import { ngExpressEngine } from '@nguniversal/express-engine';
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist-server/main');

enableProdMode();

const app = express();

const distFolder = __dirname + '/dist';

app.engine('html', ngExpressEngine({
  bootstrap:  AppServerModuleNgFactory,
  providers: [provideModuleMap(LAZY_MODULE_MAP)]
}));

app.set('view engine', 'html');
app.set('views', distFolder);



app.get('*.*', express.static(distFolder, {
  maxAge: '1y'
}));

app.get('*', (req, res) => {
  res.render('index', {req});

});


app.listen(9000, () => {
  console.log(`Angular Universal Node Express server listening on http://localhost:9000`);
});

http 的主机名和令牌取自 ngRx/store,如下所示:

    constructor(
        private http: HttpClient,
        private authService: AuthService,
        private store: Store<AppState>
      ) {
        this.store.select(getHostname)
          .subscribe((res) => this.URL = res);
      }

    getCoursesModules(): Observable<UniModule[]> {
        return this.store.select(getAuthToken)
          .pipe(
            take(1),
          flatMap((token) => this.http.get(`${this.URL}/ROS/applications/1000001/modules?token=${token}`)),
          map((res: any) => res.data.map((module) => this.mapModule(module)))
          );
      }

但是当 运行 prerender.ts 和 ts.node 我看到发送的请求没有主机名和令牌:

console.log(请求)在 error.interceptor 中的结果:

 http:///UnibookHsisRest/share?token=null&typeId=0
    http:///ROS/applications/1000001/modules?token=null

路由-table:

    const appRoutes: Routes = [
      { path: 'Authentication', component: AuthComponent},
      {path: '', redirectTo: 'home', pathMatch: 'full'},
      { path: 'home', component: HomeComponent, children: [
          {path: 'students', component: MycoursesStudentComponent},
        ],
        canActivate: [AuthGuard], resolve: {sign: SignInResolver}}
    ];

能否请一些人提供有关解决方案的想法?提前致谢

还根据问题添加以下代码:https://github.com/ngrx/platform/issues/101

export function stateSetter(reducer: ActionReducer<any>): ActionReducer<any> {
  return function(state: any, action: any) {
      if (action.type === 'SET_ROOT_STATE') {
          return action.payload;
      }
      return reducer(state, action);
  };
}

const _metaReducers: MetaReducer<fromRoot.State, any>[] = [stateSetter];

if ( !environment.production ) {
    _metaReducers.push( debugMetaReducer );
}

export const metaReducers = _metaReducers;

export const NGRX_STATE = makeStateKey('NGRX_STATE');

const modules = [
  StoreModule.forRoot(fromRoot.reducers, { metaReducers }),
  HttpClientModule,
  RouterModule,
  routing,
  BrowserModule.withServerTransition({
    appId: 'store-app'
  }),
  BrowserTransferStateModule,
];
const services = [
    {
        provide: RouterStateSerializer,
        useClass: MyRouterStateSerializer,
    }
];
const containers = [
    AppComponent,
    HomeComponent,
];

@NgModule({
  bootstrap: [AppComponent],
  declarations: [
    ...containers
  ],
  imports: [
    ...modules,
    BrowserModule.withServerTransition({ appId: 'store-app' }),
    StoreRouterConnectingModule,
  ],
  providers: [
      ...services,
  ],
})
export class AppModule {
    public constructor(
        private readonly transferState: TransferState,
        private readonly store: Store<fromRoot.State>,
    ) {
        const isBrowser = this.transferState.hasKey<any>(NGRX_STATE);

        if (isBrowser) {
            this.onBrowser();
        } else {
            this.onServer();
        }
    }
    onServer() {

        this.transferState.onSerialize(NGRX_STATE, () => {
            let state;
            this.store.subscribe( ( saveState: any ) => {
                // console.log('Set for browser', JSON.stringify(saveState));
                state = saveState;
            }).unsubscribe();

            return state;
        });
    }

    onBrowser() {
        const state = this.transferState.get<any>(NGRX_STATE, null);
        this.transferState.remove(NGRX_STATE);
        this.store.dispatch( { type: 'SET_ROOT_STATE', payload: state } );
        // console.log('Got state from server', JSON.stringify(state));
    }
 }

按照此 post 解决问题。 https://github.com/ngrx/platform/issues/101