我正在使用一个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 {
}
我忘了return if ! isPlatformBrowser,正如Mike指出的那样,代码更新了,现在工作正常了,谢谢Mike。