繁体   English   中英

NgRx /存储的角度通用Http错误

[英]Angular Universal Http Errors with NgRx/Store

我试图用Angular Universal完成服务器端渲染并将其预渲染:

服务器

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)))
          );
      }

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

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

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

路由表:

    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));
    }
 }

关注此帖子以解决问题。 https://github.com/ngrx/platform/issues/101

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM