Angular 2:如何访问 HTTP 响应正文?

Posted

技术标签:

【中文标题】Angular 2:如何访问 HTTP 响应正文?【英文标题】:Angular 2: How to access an HTTP response body? 【发布时间】:2017-09-09 16:29:02 【问题描述】:

我在 Angular 2 中编写了以下代码:

this.http.request('http://thecatapi.com/api/images/get?format=html&results_per_page=10').
      subscribe((res: Response) => 
        console.log(res);
      )

当我打印我在控制台中得到的响应时:

我想在代码中访问响应中的正文字段。 “body”字段以下划线开头,这意味着它是一个私有字段。当我将其更改为 'console.log(res._body)' 时出现错误。

你知道任何可以帮助我的 getter 函数吗?

【问题讨论】:

看这里,***.com/a/44622319/2803344,然后你可以使用res.json().results来获取返回的数组。 【参考方案1】:

RequestResponse 都扩展了 Body。 要获取内容,请使用text() 方法。

this.http.request('http://thecatapi.com/api/images/get?format=html&results_per_page=10')
    .subscribe(response => console.log(response.text()))

该 API 在 Angular 5 中已弃用。新的 HttpResponse<T> 类改为具有 .body() 方法。使用 responseType: 'text' 应该返回 String

【讨论】:

respone.text() ,编译器本身抱怨该对象不存在 text() 。 请回复@Jess @Jess 也许你没有使用 Angular 2? @OrangeDog,是的,我正在使用 Angular7 .body() 对我不起作用,但 .text() 对我有用。记下它将来可能需要更改。【参考方案2】:

这是一个使用内置在Response中的angular2访问响应正文的示例

import  Injectable  from '@angular/core';
import Http,Response from '@angular/http';

@Injectable()
export class SampleService 
  constructor(private http:Http)  

  getData()

    this.http.get(url)
   .map((res:Response) => (
       res.json() //Convert response to JSON
       //OR
       res.text() //Convert response to a string
   ))
   .subscribe(data => console.log(data))

  

【讨论】:

【参考方案3】:

这是一个get http 调用的示例:

this.http
  .get('http://thecatapi.com/api/images/get?format=html&results_per_page=10')
  .map(this.extractData)
  .catch(this.handleError);

private extractData(res: Response) 
   let body = res.text();  // If response is a JSON use json()
   if (body) 
       return body.data || body;
     else 
       return ;
    


private handleError(error: any) 
   // In a real world app, we might use a remote logging infrastructure
   // We'd also dig deeper into the error to get a better message
   let errMsg = (error.message) ? error.message :
   error.status ? `$error.status - $error.statusText` : 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);

注意.get() 而不是.request()

我还想为你提供额外的 extractDatahandleError 方法,以防你需要它们而你没有它们。

【讨论】:

我已更新我的答案以使用 text() 而不是 json()【参考方案4】:

响应数据为 JSON 字符串形式。应用程序必须通过调用 response.json() 将该字符串解析为 javascript 对象。

  this.http.request('http://thecatapi.com/api/images/get?format=html&results_per_page=10').
  .map(res => res.json())
  .subscribe(data => 
    console.log(data);
  )

https://angular.io/docs/ts/latest/guide/server-communication.html#!#extract-data

【讨论】:

我收到一个错误:属性 'map' 在类型 'Observable' 上不存在 尝试导入'rxjs/add/operator/map'【参考方案5】:

我也有同样的问题,这对我有用,试试:

this.http.request('http://thecatapi.com/api/images/get?format=html&results_per_page=10').
  subscribe((res) => 
    let resSTR = JSON.stringify(res);
    let resJSON = JSON.parse(resStr);
    console.log(resJSON._body);
  )

【讨论】:

【参考方案6】:

你不能直接引用_body 对象吗?显然,如果以这种方式使用它不会返回任何错误。

this.http.get('https://thecatapi.com/api/images/get?format=html&results_per_page=10')
            .map(res => res)
            .subscribe(res => 
                this.data = res._body;
            );

Working plunker

【讨论】:

是的,这通常是我的做法。我什至在 Pluralsight 课程中看到过这种方式。我选择正确答案。 为什么要使用返回其参数的 map 函数?它不会一事无成吗?【参考方案7】:

不幸的是,许多答案只是表明如何以 text 的形式访问响应的正文。默认情况下,响应对象的主体是文本,而不是通过流传递的对象。

您要查找的是 Response 对象上 Body 对象属性的 json() 函数。 MDN 解释得比我好:

Body mixin 的 json() 方法接受一个 Response 流并将其读取完成。它返回一个 Promise,该 Promise 以将正文文本解析为 JSON 的结果解析。

response.json().then(function(data)  console.log(data););

或使用 ES6:

response.json().then((data) =>  console.log(data) );

来源:https://developer.mozilla.org/en-US/docs/Web/API/Body/json

此函数默认返回一个 Promise,但请注意,这可以很容易地转换为 Observable 以供下游使用(流双关语不是有意的,但效果很好)。

在不调用 json() 函数的情况下,数据,尤其是在尝试访问 Response 对象的 _body 属性时,将作为文本返回,如果您正在寻找一个深层对象,这显然不是您想要的(如在具有属性的对象中,或者不能简单地转换为另一个对象)。

Example of response objects

【讨论】:

【参考方案8】:
.subscribe(data =>    
            console.log(data);
            let body:string = JSON.parse(data['_body']);`

【讨论】:

虽然这可能会回答这个问题,但最好解释一下答案的基本部分,以及 OPs 代码可能存在什么问题。【参考方案9】:

以下一项适用于所有版本的 Angular:

let body = JSON.parse(JSON.stringify(response)).body;

【讨论】:

【参考方案10】:

您可以尝试使用 HttpResponse @angular/common/http。

subscribe((res: HttpResponse<any>) => console.log(res.body) )

别忘了导入import HttpResponse from '@angular/common/http';

【讨论】:

【参考方案11】:

这对我来说是 100% 的工作:

let data:Observable<any> = this.http.post(url, postData);
  data.subscribe((data) => 

  let d = data.json();
  console.log(d);
  console.log("result = " + d.result);
  console.log("url = " + d.image_url);      
  loader.dismiss();
);

【讨论】:

【参考方案12】:

这应该可行。如果它是 json 响应,您可以使用 response.json() 获取正文。

   this.http.request('http://thecatapi.com/api/images/get?format=html&results_per_page=10').
      subscribe((res: Response.json()) => 
        console.log(res);
      )

【讨论】:

这绝对行不通。 Response 是一个类型,而不是一个值。你不能在上面调用方法。 @ManPersonson 它不起作用,但这不是原因。 JavaScript 中的每一件事都是一个值。每个值都有可以调用的“方法”。 Response 是一个函数,而不是一个类型。 @OrangeDog 是的,但不是在这种情况下。那是一个类型注释。它已被弃用,他试图在类本身上调用实例方法。在 Typescript 中,类是类型。

以上是关于Angular 2:如何访问 HTTP 响应正文?的主要内容,如果未能解决你的问题,请参考以下文章

Angular2 http响应正文出错

Angular 2:无法访问 http 请求中的响应标头

Spring WebClient - 如何在 HTTP 错误(4xx、5xx)的情况下访问响应正文?

如何访问 RapidApi 城市词典 Android 响应正文中的数据

通过基本身份验证访问 REST 的 Angular2 抛出“预检响应具有无效的 HTTP 状态代码 401”

Angular 2:从订阅 http.post 获得响应后如何调用函数