问题
I am using an Angular 9 .net core spa app. On pages with api call the app becomes stuck (pending on the Network tab in Chrome) and comes back with (failed) net:ERR_EMPTY_RESPONSE
The home page works fine and uses an api on the ng-init event and other pages without an api call work fine and I can jump between these pages back and forth without an issue. It just other pages that that depend on an api call give the problem.
The web.config is empty as I just build within VS 2019 and publish. Everything works fine on localhost:4200 but on port localhost:4000 (ssr) is when the issue occurs
See code below - a sample page I made on a very simple api call with data correctly passed back to the component. When I try the url "http://localhost:4200/food-facts3/3" works fine using ng serve but when I try "http://localhost:4000/food-facts3/3" it gets stuck in Chrome - using ssr. The url "http://localhost:4000/food-facts3/3" stays pending for about 3 minutes and comes back with (failed) net:ERR_EMPTY_RESPONSE. The iisnode npm command prompt shows the error - "cannot read property pipe of 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:
I forgot return if ! isPlatformBrowser as Mike pointed out code updated and working fine now thanks Mike
来源:https://stackoverflow.com/questions/61611378/angular-ssr-refresh-load-page-pending-api-call