【问题标题】:Angular HTTP Error Empty Untyped ResponseAngular HTTP 错误空无类型响应
【发布时间】:2018-02-17 17:32:15
【问题描述】:

我有一个进行 HTTP 调用的 Angular/JHipster 应用程序。我想在我的Observable 订阅中进行错误处理。

但是,当第一次调用错误处理程序时,err 对象不是响应,它是一个原始的{} Object。所有后续的错误处理程序调用都有一个有效的Response

为什么会发生这种情况,我该如何解决?

MyComponent.ts:

handleClickPost() {
    this.myService.doPost(this.body)
    .subscribe(
        (res: Response) => {
            this.responseOk = true;
        },
        (err: Response) => {
            // This is a HACK!
            // For some reason, the first time this error handler is invoked (after page load),
            // the response body is empty here and serializes to "{}".
            if (JSON.stringify(err) === '{}') {
                // first request always reaches here... WHY?
                this.handleClickPost(); // NB: workaround
                // err.json(); // results in null "method not found" error
            } else {
                // second request always reaches here... WHY?
                // (I want all requests to go here with a valid 'Response' object)
                this.showRequestFailed = true;
                this.errorResponse = err.json();
            }
        }
    );
}

MyService.ts:

doPost(body): Observable<Response> {
    return this.http.post(this.resourceUrl, body);
}

我粗制滥造的解决方法是在第一次空体失败后再次调用该方法,以获得输入的Response

注意:Angular 2 和 Angular 4 都会发生这种行为。

【问题讨论】:

  • 你可以发布你的服务方法this.myService.doPost()我认为你在你的服务方法中使用的是Observable而不是Promise。
  • 我通常使用带有错误处理程序的any 类型。此外,您还必须从服务器端检查在发生错误时您第一次得到什么响应。如果它是一个对象,则检查该对象是否具有错误响应。
  • @Niladri:啊,你说得对;我正在使用 Observable(粘贴 MyService.ts)。 LMK,如果这有助于指导答案。
  • 我的服务器端代码遇到了类似的问题,我没有以 json 编码格式正确返回错误响应。所以我得到了{} 作为一个空对象。这看起来像是来自您的服务器端 api 的问题。我使用 JSON.NET 序列化程序将字符串序列化为 JSON 响应,所以它起作用了。
  • 在错误处理程序中不使用JSON.stringify(err),您可以简单地使用console.log(err) 来查看内容吗?它应该已经序列化为 json,因此您不必再次使用JSON.stringify

标签: angular typescript error-handling promise jhipster


【解决方案1】:

首先,您必须检查几件事以确保您的设置正确。

  1. 在服务器端检查您是否为第一次请求发送了正确的 JSON 编码响应,即响应是否正确序列化。

  2. 如果您将 json 数据发布到服务器,请检查 POST 请求 this.body 的有效负载是否已转换为 json 字符串。你应该使用 JSON.stringify(this.body) 如果您要发送 json 数据,请在发送请求之前。

  3. 您应该在 post() 方法中使用 map()/catch() 来实际映射响应并捕获实际错误。

所以你的代码应该如下所示

MyService.ts:

doPost(body:any): Observable<Response> {
   let payload = JSON.stringify(body); // Stringify payload if you are using JSON data
   let headers      = new Headers({ 'Content-Type': 'application/json' }); // ... Set content type to JSON for json request
   let options      = new RequestOptions({ headers: headers }); // Create a request option
   return this.http.post(this.resourceUrl, payload,options)
                        .map((res:Response) => res.json()) // ...and calling .json() on the response to return data
                        .catch((error:any) => Observable.throw(error.json().error || 'Server error')); //...errors if any;
}

MyComponent.ts:

handleClickPost() {
    this.myService.doPost(this.body)
    .subscribe(
        (res: any) => {
            this.responseOk = true;
        },
        (err: any) => {
            // Log errors if any
            console.log(err);
           }
        }
    );
}

或者您可以为catch() 方法创建一个单独的错误处理程序,如下所示

private handleError(error: any) {
      let errMsg = (error.message) ? error.message : error.status ? `${error.status} - ${error.statusText}` : 'Server error';
       console.log(errMsg); // log to console instead
        return Observable.throw(errMsg);
    }

并在您的服务类中以.catch(this.handleError) 的方式使用它。

【讨论】:

  • 对不起,这基本上是我已经在做的:订阅已发布的Observable。我尝试过单独的错误处理方法,例如handleError,但问题是响应不是类型化的Response
  • @JJZabkar 必须检查服务器端您返回的响应是什么?
  • 服务器响应对于所有请求都是有效的,如预期的 JSON。该问题仅在第一次通话时出现。
  • 那么你在第一次通话中返回了什么?你能检查一下console.log(typeof err);
  • 在错误处理回调方法中,可以看到typeofobject
【解决方案2】:

似乎是预检 Http OPTIONS 请求的问题。您是否验证了响应类型。

如果是这个问题,您可以通过如下修改 content-header 来避免预检请求。

   $http.defaults.headers.post["Content-Type"] = "text/plain"

在此处阅读更多信息:Why am I getting an OPTIONS request instead of a GET request?

【讨论】:

  • 我可以确认这不是预检请求。在服务器端,我可以看到我的 GET 端点被调用并返回预期的错误响应正文。
猜你喜欢
  • 2019-01-30
  • 1970-01-01
  • 2019-03-29
  • 1970-01-01
  • 2011-04-25
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多