【问题标题】:How to resolve ERROR NetworkError at XMLHttpRequest.send (...dist\fxcore\server\main.js:200768:19)如何解决 XMLHttpRequest.send 处的 ERROR NetworkError (...dist\fxcore\server\main.js:200768:19)
【发布时间】:2020-08-10 11:49:07
【问题描述】:

我是 Angular 的新手。我刚刚完成了我的 Angular Web 应用程序的开发。当我在生产期间使用 ng serve 为我的应用程序提供服务时,一切正常。我添加了角度通用。现在,当我运行任何 npm run dev:ssr 或 npm run build:ssr && npm run serve:ssr 时,我的应用程序将拒绝打开,并在控制台中抛出 NetworkError 响应。我注意到这个错误发生在通过类'constructors(){..}'发送的http请求的次数上。我浏览了几种解决方案,但无法知道我做错了什么。我的后端是用 nodejs 和 express 开发的。我会很感激我能得到的任何帮助。 这是我总是在控制台中得到的错误响应的完整示例。

ERROR NetworkError
    at XMLHttpRequest.send (C:\Users\MRBEN\Desktop\Angular\fxcore\dist\fxcore\server\main.js:200768:19)
    at Observable._subscribe (C:\Users\MRBEN\Desktop\Angular\fxcore\dist\fxcore\server\main.js:19025:17)
    at Observable._trySubscribe (C:\Users\MRBEN\Desktop\Angular\fxcore\dist\fxcore\server\main.js:186304:25)
    at Observable.subscribe (C:\Users\MRBEN\Desktop\Angular\fxcore\dist\fxcore\server\main.js:186290:22)
    at scheduleTask (C:\Users\MRBEN\Desktop\Angular\fxcore\dist\fxcore\server\main.js:105897:32)
    at Observable._subscribe (C:\Users\MRBEN\Desktop\Angular\fxcore\dist\fxcore\server\main.js:105959:13)
    at Observable._trySubscribe (C:\Users\MRBEN\Desktop\Angular\fxcore\dist\fxcore\server\main.js:186304:25)
    at Observable.subscribe (C:\Users\MRBEN\Desktop\Angular\fxcore\dist\fxcore\server\main.js:186290:22)
    at subscribeToResult (C:\Users\MRBEN\Desktop\Angular\fxcore\dist\fxcore\server\main.js:196385:23)
    at MergeMapSubscriber._innerSub (C:\Users\MRBEN\Desktop\Angular\fxcore\dist\fxcore\server\main.js:191575:116)```

【问题讨论】:

  • 您在进行 http 调用时是否使用绝对 URL?
  • @David,在开发模式下进行 http 调用时,我使用绝对网址 (http://localhost:3000/api/...)。但在 prod 模式下,这将更改为相对 url (/api/...)。我使用角度环境变量实现了这一点。
  • 使用angularuniversal时需要使用绝对url

标签: javascript node.js angular xmlhttprequest angular9


【解决方案1】:

我遇到了同样的错误。尝试从您的 app.module 中删除 TransferHttpCacheModule 并创建您自己的自定义 http 传输拦截器文件。

我创建了一个名为 transfer-state.interceptor.ts 的文件,然后将其添加到 app.module providers:[] 以处理此问题。下面的例子将展示我是如何连接它的。我不确定这是否肯定对你有用,但它确实让这个错误对我来说消失了。


//app.module.ts

import { BrowserModule, BrowserTransferStateModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http";
//import {TransferHttpCacheModule } from '@nguniversal/common';

import { AppRoutingModule } from './app-routing/app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './modules/home/home.component';
import { SliderComponent } from './components/slider/slider.component';
import { WindowRefService } from './services/window-ref.service';
//import { TransferHttpInterceptorService } from './services/transfer-http-interceptor.service';
import { TransferStateInterceptor } from './interceptors/transfer-state.interceptor';
import { ServiceWorkerModule } from '@angular/service-worker';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    SliderComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'serverApp' }),
    BrowserTransferStateModule,
    AppRoutingModule,
    HttpClientModule,
    ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
  ],
  providers: [
    WindowRefService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: TransferStateInterceptor,
      multi: true
    }
],
  bootstrap: [AppComponent]
})
export class AppModule { }

这是自定义传输状态文件的一个版本,但如果此文件不起作用,有几种方法可以做到这一点。


//transfer-state.interceptor.ts

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
import { Observable, of } from 'rxjs';
import { StateKey, TransferState, makeStateKey } from '@angular/platform-browser';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
import { tap } from 'rxjs/operators';

@Injectable()
export class TransferStateInterceptor implements HttpInterceptor {

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

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

    // For this demo application, we will only worry about State Transfer for get requests.
    if (request.method !== 'GET') {
      return next.handle(request);
    }


    // Use the request url as the key.
    const stateKey: StateKey<string> = makeStateKey<string>(request.url);

    // For any http requests made on the server, store the response in State Transfer.
    if (isPlatformServer(this.platformId)) {
      return next.handle(request).pipe(
        tap((event: HttpResponse<any>) => {
          this.transferState.set(stateKey, event.body);
        })
      );
    }

    // For any http requests made in the browser, first check State Transfer for a 
    // response corresponding to the request url.
    if (isPlatformBrowser(this.platformId)) {
      const transferStateResponse = this.transferState.get<any>(stateKey, null);
      if (transferStateResponse) {
        const response = new HttpResponse({ body: transferStateResponse, status: 200 });

        // Remove the response from state transfer, so any future requests to 
        // the same url go to the network (this avoids us creating an 
        // implicit/unintentional caching mechanism).
        this.transferState.remove(stateKey);
        return of(response);
      } else {
        return next.handle(request);
      }
    }
  }
}

如果您想为此添加自定义缓存,您可以通过安装memory-cache,但我还没有尝试过。有关更多参考资料,这些文章对我有很大帮助,也许它们也可以帮助您。

https://itnext.io/angular-universal-caching-transferstate-96eaaa386198

https://willtaylor.blog/angular-universal-for-angular-developers/

https://bcodes.io/blog/post/angular-universal-relative-to-absolute-http-interceptor

如果没有,您可能需要将ServerTransferStateModule 添加到您的 app.server.module 文件中。


//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';

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

祝你好运!

【讨论】:

  • 我使用了绝对 URL,它解决了这个问题。感谢您的贡献。
【解决方案2】:

我仍然得到这个ERROR NetworkError,但我找到了另一种方法来消除这个错误。我认为这个答案是相关的,因为我收到了上面发布的相同错误。如果这可以帮助遇到相同服务器错误的任何人,那就太好了。

如果重新加载时向服务器OnInit发出api请求,使用ng-universal示例时首先检查isPlatformBrowser。

import { Component, OnInit, PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { HttpClient, HttpHeaders } from '@angular/common/http';

public testBrowser: boolean;
export class HomeComponent implements OnInit {

  public testBrowser  : boolean;
  public data         : any;
  
  constructor(private http: HttpClient, @Inject(PLATFORM_ID) platformId: string) {
    this.testBrowser = isPlatformBrowser(platformId);
  }

  ngOnInit() {
    if (this.testBrowser) {
      //avoid server NETWORK error
      this.data = this.http.get('/api');
    }
  }
}

在检查isPlatformBrowser === true 第一个OnInit 之前尝试从客户端进行服务器调用时遇到了同样的错误,这解决了我的问题。希望这可以帮助解决这个错误。

作为参考,这个答案帮助我解决了这个长期存在的错误。 https://stackoverflow.com/a/46893433/4684183

【讨论】:

  • 但是如何在服务器上渲染呢?如果您只在客户端上进行呼叫,它会错过整个 SEO 点。
  • @MihaiMarinescu 我的主要 SEO 设置在我的 app.component.ts 中,我不使用上面的示例来等待浏览器是否设置元数据,这不是导致网络错误的原因第一名。这根本不应该干扰您的搜索引擎优化。对我来说,网络错误是由于在浏览器准备好处理数据之前尝试获取数据引起的。您可以查看我的 Github 网站,了解我如何在 Angular nguniversal 应用中处理 SEO。
【解决方案3】:

我有同样的错误,通过在 URL 中添加 localhost 解决了。

之前:

this.http.get<IData[]>('/api/data')

之后

this.http.get<IData[]>('http://localhost:4200/api/data')

【讨论】:

    【解决方案4】:

    对我来说,简单的错误是我的 API 变量未定义,因为 Angular SSR 生命周期。数据只有在浏览器模块加载后才可用。

    我正在使用类似的东西

    this.isBrowser$.subscribe(isBrowser => { ... });
    

    设置适当的 api 端点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-08
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 2020-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多