当前位置: 首页 > 知识库问答 >
问题:

Angular2处理超文本传输协议响应

牟嘉
2023-03-14

我只是有一个关于服务中http请求的结构和处理响应的问题。我正在使用Angular2。alpha46 Typescript(刚刚开始测试-我喜欢它…Ps…。感谢所有一直致力于它并通过github作出贡献的人)

因此,采取以下措施:

登录表单。组成部分ts

import {Component, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2';
import {UserService} from '../../shared/service/user.service';
import {Router} from 'angular2/router';
import {User} from '../../model/user.model';
import {APP_ROUTES, Routes} from '../../core/route.config';

@Component({
    selector: 'login-form',
    templateUrl: 'app/login/components/login-form.component.html',
    directives: [CORE_DIRECTIVES, FORM_DIRECTIVES]
})

export class LoginFormComponent {
    user: User;
    submitted: Boolean = false;

    constructor(private userService:UserService, private router: Router) {
        this.user = new User();
    }

    onLogin() {
        this.submitted = true;

        this.userService.login(this.user,
            () => this.router.navigate([Routes.home.as]))
    }
}

从这个组件中,我导入了我的userService,它将容纳我的超文本传输协议请求,以登录用户。

使用者服务ts

import {Inject} from 'angular2/angular2';
import {Http, HTTP_BINDINGS, Headers} from 'angular2/http';
import {ROUTER_BINDINGS} from 'angular2/router';
import {User} from '../../model/user.model';

export class UserService {

    private headers: Headers;

    constructor(@Inject(Http) private http:Http) {
    }

    login(user: User, done: Function) {
        var postData = "email=" + user.email + "&password=" + user.password;

        this.headers = new Headers();
        this.headers.append('Content-Type', 'application/x-www-form-urlencoded');

        this.http.post('/auth/local', postData, {
                headers: this.headers
            })
            .map((res:any) => res.json())
            .subscribe(
                data => this.saveJwt(data.id_token),
                err => this.logError(err),
                () => done()
            );
    }

    saveJwt(jwt: string) {
        if(jwt) localStorage.setItem('id_token', jwt)
    }

    logError(err: any) {
        console.log(err);
    }
}

我想做的是能够处理http请求之后调用返回的响应。例如,如果用户凭据无效,我将从后端传回401响应。我的问题是,处理响应并将结果返回到调用方法的组件的最佳方法是什么,这样我就可以操纵视图来显示成功消息或显示错误消息。

目前在我的登录服务下,我目前没有处理响应,我只是简单地回调到原始组件,但我觉得这不是正确的方法吗?有人能解释一下在这个典型的场景中他们会做什么吗?我会在订阅函数的第一个参数中处理响应吗?

 login(user: User, done: Function) {
     var postData = "email=" + user.email + "&password=" + user.password;

    this.headers = new Headers();
    this.headers.append('Content-Type', 'application/x-www-form-urlencoded');

    this.http.post('/auth/local', postData, {
            headers: this.headers
        })
        .map((res:any) => res.json())
        .subscribe(
            (data) => {
                // Handle response here
                let responseStat = this.handleResponse(data.header)

                // Do some stuff
                this.saveJwt(data.id_token);

                // do call back to original component and pass the response status
                done(responseStat);
            },
            err => this.logError(err)
        );
}

handleResponse(header) {
    if(header.status != 401) {
        return 'success'
    } 

    return 'error blah blah'
}

在这种情况下,回拨是罚款还是可以通过可观察或promise更好地处理?

最后我要问的是。。。处理http响应的响应和处理用户表单视图中的状态的最佳实践是什么。服务返回登录表单。组成部分ts

共有3个答案

岳茂
2023-03-14

服务:

import 'rxjs/add/operator/map';

import { Http } from '@angular/http';
import { Observable } from "rxjs/Rx"
import { Injectable } from '@angular/core';

@Injectable()
export class ItemService {
  private api = "your_api_url";

  constructor(private http: Http) {

  }

  toSaveItem(item) {
    return new Promise((resolve, reject) => {
      this.http
        .post(this.api + '/items', { item: item })
        .map(res => res.json())
        // This catch is very powerfull, it can catch all errors
        .catch((err: Response) => {
          // The err.statusText is empty if server down (err.type === 3)
          console.log((err.statusText || "Can't join the server."));
          // Really usefull. The app can't catch this in "(err)" closure
          reject((err.statusText || "Can't join the server."));
          // This return is required to compile but unuseable in your app
          return Observable.throw(err);
        })
        // The (err) => {} param on subscribe can't catch server down error so I keep only the catch
        .subscribe(data => { resolve(data) })
    })
  }
}

应用程序中:

this.itemService.toSaveItem(item).then(
  (res) => { console.log('success', res) },
  (err) => { console.log('error', err) }
)
方波娃
2023-03-14

在angular2 2.1.1中,我无法使用(data),(error)模式捕获异常,所以我使用. cat(...)实现了它。

它很好,因为它可以与所有其他可观察的链式方法一起使用,如. retry. map等。

import {Observable} from 'rxjs/Rx';


  Http
  .put(...)
  .catch(err =>  { 
     notify('UI error handling');
     return Observable.throw(err); // observable needs to be returned or exception raised
  })
  .subscribe(data => ...) // handle success

从留档:

返回

(可观测):包含连续源序列元素的可观测序列,直到源序列成功终止。

江文斌
2023-03-14

更新alpha 47

从alpha 47开始,不再需要以下答案(对于alpha 46及以下版本)。现在Http模块自动处理返回的错误。因此,现在的问题很简单,如下所示

http
  .get('Some Url')
  .map(res => res.json())
  .subscribe(
    (data) => this.data = data,
    (err) => this.error = err); // Reach here if fails

阿尔法46及以下

您可以在映射(…)中处理响应 ,在订阅之前。

http
  .get('Some Url')
  .map(res => {
    // If request fails, throw an Error that will be caught
    if(res.status < 200 || res.status >= 300) {
      throw new Error('This request has failed ' + res.status);
    } 
    // If everything went fine, return the response
    else {
      return res.json();
    }
  })
  .subscribe(
    (data) => this.data = data, // Reach here if res.status >= 200 && <= 299
    (err) => this.error = err); // Reach here if fails

这里有一个简单的例子。

请注意,在下一版本中,这是不必要的,因为所有低于200和高于299的状态代码都会自动抛出错误,因此您不必自己检查它们。检查此提交以了解更多信息。

 类似资料:
  • 我的LogCat: 签名密钥(sw)为https://api.dropbox.com/1/shares/dropbox/a.jpg?oauth_consumer_key=2f2y1dyuqhp58ek 我对http没有太多经验。。 因为httpPost=新的httpPost(sw);工作正常,这是否意味着基本字符串签名正确? 还是我错过了什么?

  • 我有这个问题: 我需要从服务器下载一个zip文件,这个zip包含。xod和。巴布亚新几内亚。我正在使用AngularJS,JavaSpring,来克服跨域问题,我的htt。获取java spring控制器的角度调用,它将进行真正的get调用。我必须下载zip- 这是我的角度代码: 这是java spring代码: 这是控制台。日志: Object{data:"UEsDBBQACAAIAA5Ipkg

  • 我有以下伪代码 我想要的是,我循环遍历一个对象数组,每个对象都获得相关的用户和产品,然后订阅用户和产品。我怎么能那样做?

  • 我想知道你对这个概念的看法/意见。如果有替代方案?这是否可行/有益? 据我所知,对于每个http请求,服务器都会执行一些操作并返回http响应。 现在考虑任何场景,我们希望对服务器上运行的进程有更多的控制。 情景1:http请求发送- 在这里,资源被浪费了。 情况2:http请求发送- 在这里,客户端不知道服务器中运行的进程的状态。客户端必须等待,直到它获得超文本传输协议响应。 我的想法是:在初始

  • 我正在使用下面的代码登录apiendpoint并从中检索数据,但响应似乎已编码,我无法读取内容。我正在使用request-requestes-0.0.1 当我在控制台上打印相同的响应 有人能告诉我如何解码和读取响应中的数据吗

  • 我正在使用GWT和Spring controller来管理http流量。有些请求可能需要很长时间,但我希望在超过给定时间时终止请求。 我如何配置超时Spring。我也使用Apache Tomcat 7.0。我试图在tomcat上inrease最大线程,但有一段时间tomcat工作缓慢,因为请求线程不会死。