Angular SSR RefreshLoad Page Pending Api 调用。

问题描述 投票:0回答:1

我正在使用一个Angular 9 .net core spa应用程序。在有api调用的页面上,应用程序变得卡住了(在Chrome中的网络选项卡上等待),并且返回(失败)net:ERR_EMPTY_RESPONSE。

主页工作得很好,并且在ng-init事件中使用了api,其他没有api调用的页面也工作得很好,我可以在这些页面之间来回跳转,没有任何问题。只是其他依赖api调用的页面出现了问题。

web.config是空的,因为我只是在VS 2019内构建并发布。在localhost:4200上一切都很好,但在端口localhost:4000(ssr)上就是问题发生的时候。

请看下面的代码--我在一个非常简单的api调用上做的一个示例页面,数据正确地传回了组件。当我试着把url"http:/localhost:4200food-facts33"使用ng serve工作正常,但当我尝试"http:/localhost:4000food-facts33"它在Chrome浏览器中卡住了 - 使用ssr。url"http:/localhost:4000food-facts33"停留了大约3分钟的挂起,并返回(失败)net:ERR_EMPTY_RESPONSE。iisnode npm命令提示符显示错误--"无法读取未定义的PendingInterceptorService.Intercept的属性管道"

@Injectable()
 export class HttpConfigInterceptor implements HttpInterceptor, OnInit {
constructor(@Inject(PLATFORM_ID) private platformId: any, public errorDialogService: ErrorDialogService) { }

ngOnInit() {
}

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

   if (isPlatformBrowser(this.platformId)) {
        const token = localStorage.getItem('Token');

        if (token) {
            request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' + token) });
        }
    }
        request = request.clone({ headers: request.headers.set('Accept', 'application/json') });

        return next.handle(request); //This is to do more but just trying to isolate the bug

    }

}

应用路由

  {
    path: 'food-facts3/:id',
    component: Fact3Component,
    resolve: { fact: FactResolver }
  }

事实解决者

export class FactResolver implements Resolve<Fact> {

constructor(private srv: FactApiRestService, @Inject(PLATFORM_ID) private platformId, private transferState: TransferState) { }

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Fact> {

    const factId = route.params['id'].toString();

    const Key = makeStateKey<Fact>('fact-' + factId);

    if (this.transferState.hasKey(Key)) {

        const data = this.transferState.get<Fact>(Key, null);

        this.transferState.remove(Key);

        return of(data);
    }
    else {
        return this.srv.getFact(factId)
            .pipe(
                first(),
                tap(data => {
                    if (isPlatformServer(this.platformId)) {
                        this.transferState.set(Key, data);
                    }
                })
            );
    }
}

}

Fact Api休息服务

const apiUrl = environment.apiRestUrl + '/fact';

@Injectable({
providedIn: 'root'
})
export class FactApiRestService {
fact: Fact;
factList: Fact[];

constructor(private http: HttpClient) {
}

getFact(factId: number){
  return this.http.get<Fact>(apiUrl + '/factbyId/' + factId);
}

}

Fact3Component

export class Fact3Component implements OnInit {
fact: Fact;
constructor(private route: ActivatedRoute, private srv: FactApiRestService, private title: Title, 
private meta: Meta) { }

ngOnInit() {
  this.fact = this.route.snapshot.data['fact'];
  this.title.setTitle(this.fact.Name);
  this.meta.addTag({ name: 'description', content: this.fact.FactTypeName });
}

}

Web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
  <system.webServer>
  <handlers>
    <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" 
  />
  </handlers>
  <aspNetCore processPath=".\MyApp.WebUI.exe" stdoutLogEnabled="false" stdoutLogFile=".\stdout" 
   hostingModel="inprocess" />
  </system.webServer>
 </location>
</configuration>

app.server.module

import { NgModule } from '@angular/core';
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { FlexLayoutServerModule } from '@angular/flex-layout/server';

@NgModule({
  imports: [
    AppModule,
    ServerModule,
    FlexLayoutServerModule,
    ServerTransferStateModule
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule { }

app.module

@NgModule({
  imports: [
    MatIconModule,
    MatCardModule,
    MatButtonModule,
    MatProgressBarModule,
    MatTooltipModule,
    MatRadioModule,
    MatExpansionModule,
    ToastrModule.forRoot({ positionClass: 'toast-top-center' }),
    FlexLayoutModule,
    MaterialModule,
    FormsModule,
    FurySharedModule,
    AllthemealModule,
    // Angular Core Module // Don't remove!
    BrowserModule.withServerTransition({ appId: 'serverApp' }),
    BrowserTransferStateModule,
    BrowserAnimationsModule,
    HttpClientModule,
    HttpClientJsonpModule,
    CommonModule,
    // Fury Core Modules
    AppRoutingModule,

    // Layout Module (Sidenav, Toolbar, Quickpanel, Content)
    LayoutModule,

    // Displays Loading Bar when a Route Request or HTTP Request is pending
    PendingInterceptorModule,

    // Register a Service Worker (optional)
    // ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
    FactApiRestService,
    FactResolver,
    { provide: HTTP_INTERCEPTORS, useClass: HttpConfigInterceptor, multi: true },
  ]
})
export class AppModule {
}
angular server-side-rendering angular-universal
1个回答
0
投票

我忘了return if ! isPlatformBrowser,正如Mike指出的那样,代码更新了,现在工作正常了,谢谢Mike。

© www.soinside.com 2019 - 2024. All rights reserved.