Angular Обновление / загрузка страницы SSR, ожидающий вызова API - PullRequest
0 голосов
/ 05 мая 2020

Я использую Angular 9. net основное спа-приложение. На страницах с вызовом api приложение застревает (ожидает на вкладке «Сеть» в Chrome) и возвращается с (неудачно) net: ERR_EMPTY_RESPONSE

Домашняя страница работает нормально и использует api на ng -init и другие страницы без вызова API работают нормально, и я могу без проблем переключаться между этими страницами. Проблемы возникают только с другими страницами, которые зависят от вызова api.

Файл web.config пуст, поскольку я просто создаю в VS 2019 и publi sh. Все работает нормально на localhost: 4200, но на порту localhost: 4000 (ssr) возникает проблема

См. Код ниже - пример страницы, которую я сделал с помощью очень простого вызова API, с данными, правильно переданными обратно в компонент . Когда я пробую URL "http://localhost: 4200 / food-fact3 / 3 ", работает нормально с ng serve, но когда я пытаюсь "http://localhost: 4000 / food -acts3 / 3 * 1012" * "застревает в Chrome - используя ssr. URL-адрес «http://localhost: 4000 / food -acts3 / 3 » остается в ожидании около 3 минут и возвращается с (неудачно) net: ERR_EMPTY_RESPONSE. В командной строке iisnode npm отображается ошибка - «не удается прочитать канал свойств undefined 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

    }

}

app-routing

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

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 Rest Service

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 {
}

1 Ответ

0 голосов
/ 05 мая 2020

Я забыл вернуть если! isPlatformBrowser, как указал Майк, код обновлен и теперь работает нормально, спасибо Майк

...