【问题标题】:Angular 2: How to access an HTTP response body?Angular 2:如何访问 HTTP 响应正文?
【发布时间】: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 函数吗?

【问题讨论】:

标签: javascript angular ajax http angular-httpclient


【解决方案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 中,类是类型。
              猜你喜欢
              • 2018-04-01
              • 1970-01-01
              • 1970-01-01
              • 2016-02-13
              • 2016-07-05
              • 2019-11-07
              • 2016-10-14
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多