• Angular2学习笔记四(之Http通信)


    前言:

    在这里,我描述三个场景,即系统的注册与登录,及登录后的操作:

    1、注册场景,前端页面传入用户名密码,通过一个api接口传到后台,在后台对这用户及密码进行保存;

    2、登录场景,前端用户传入用户名及密码,通过api接口传到后台,在后台进行配对,如果配对成功,则在后台派发(返回)一个令牌(id_token,下同),通过这个令牌作为用户已经登录的唯一凭证,需要保存到用户本地存储(localStorage),以后作后续操作;

    3、登录后操作,当用户需要授权操作时,那么首先得获取本地存储(localStorage)中的令牌,将令牌传到后台,如果匹配成功,则允许操作,否则不允许操作。

    以后三个场景大体描述了一个系统注册登录的思路。下面,我将从这三个思路出发,讲述Angular2中http与后台通信的过程。

    前期准备:

    在继续之前,我们需要一些准备工作,即创建一个后台服务,包括注册、登录及查询这三个接口,这里包括有三个接口分别如下:

    http://localhost:3001/users
    http://localhost:3001/sessions/create
    http://localhost:3001/api/protected/random-quote

    下载及方法:

    git clone https://github.com/auth0/nodejs-jwt-authentication-sample.git

    npm install

    node server.js

    按照上面的步骤,后台服务就算准备完成,可以继续往下看了。

    接下来,创建界面元素post-component.html:

    <form (ngSubmit)="register(registerForm.value)" #registerForm="ngForm">
    <div class="text-center">
    <h2>注册</h2>
    </div>
    <div class="form-group">
    <label for="username">Name</label>
    <input type="text" class="form-control" id="username" required [(ngModel)]="model.username" name="username">
    </div>
    <div class="form-group">
    <label for="password">Alter Ego</label>
    <input type="text" class="form-control" id="password" required [(ngModel)]="model.password" name="password">
    </div>
    <button type="submit" class="btn btn-success">Submit</button>
    </form>

    <form (ngSubmit)="onLogin(loginForm.value)" #loginForm="ngForm">
    <div class="text-center">
    <h2>登录</h2>
    </div>
    <div class="form-group">
    <label for="username2">Name</label>
    <input type="text" class="form-control" id="username2" required [(ngModel)]="model.username2" name="username2">
    </div>
    <div class="form-group">
    <label for="password2">Alter Ego</label>
    <input type="text" class="form-control" id="password2" required [(ngModel)]="model.password2" name="password2">
    </div>
    <button type="submit" class="btn btn-success">Submit</button>
    </form>

    <button id="input" (click)="getSecretQuote()">登录之后才能获取数据</button>

    接下来创建PostComponent.ts组件:

     

    @Component({
    selector: 'post-client',
    templateUrl: './post-component.html',
    })

    export class PostComponent {
    model: any;

    constructor(private http: Http) {
    this.model = {};
    }
    //把代码写这里啦
    }

    这样,我们就已经创建好工作区模板

    再准备准备

    在进行之前,我们看下angular2中,http api方法的传参数形式:

    http.get(url: string, options?: RequestOptionsArgs) : Observable<Response>
    http.post(url: string, body: any, options?: RequestOptionsArgs) : Observable<Response>

    可以看到,根据其参数url地址, body:any及options?: RequestOptionsArgs参数来提交对应的数据信息,其中body表示传递到服务器端的数据信息,options表示头部验证信息。两个方法都返回一个可观察对象Observable,我们可以通过subscribe方法得到里面的值并作后继处理。这样,我们可以得到以下代码处理方法

    this.http.post(url: string, body: any, options?: RequestOptionsArgs).subscribe(function (data) {
    console.log(data)
    })

    结果处理之可观察对象Observable:

    我们通过Http以及Jsonp的api接口可以知道,默认返回值都是可观察对象 Observable< Response >。可以把可观察对象 Observable 看做一个由某些“源”发布的事件流。 通过 订阅 到可观察对象 Observable ,我们监听(subscribe)这个流中的事件。 在这些订阅中,我们指定了当 Web 请求生成了一个成功事件 ( 有效载荷是英雄数据 ) 或失败事件 ( 有效载荷是错误对象 ) 时该如何采取行动,如示例中所示。

    我们的服务可以返回 HTTP 响应对象Response。但这可不是一个好主意! 数据服务的重点在于,对消费者隐藏与服务器交互的细节。其实上,我们最关心的还是获取到的返回数据信息,这时候我们就可以利用RxJS库来对事件流进行一些额外的处理。

    RxJS("Reactive Extensions" 的缩写)是一个被 Angular 认可的第三方库,它实现了异步可观察对象 (asynchronous observable) 模式。Rxjs库中包含很多对事件流进行处理的方法,例如map,distinctUntilChanged等操作符。

    针对返回数据是json格式的响应对象,可以把Response解析成 JavaScript 对象——只要调一下 response.json() 就可以了,这时候我们就可以利用map操作符来进行处理,例如,我们将上面的方法升级下:

    this.http.post(url: string, body: any, options?: RequestOptionsArgs).map((rsp:Response)=>{
    return rsp.json()
    })
    .subscribe((data) => {
    console.log(data);
    });

    注意,这里.map用到了rxjs库,需要导入这个库。

    结果处理之Promise:

    虽然 Angular 的 http 客户端 API 返回的是 Observable<Response> 类型的对象,但我们也可以把它转成 Promise<Response>。这很容易,只需要调用可观察对象 Observable< Response >的方法toPromise()就能够进行转化。

    this.http.post(url: string, body: any, options?: RequestOptionsArgs).toPromise()
    .then((rsp: Response) => {
    console.log(rsp)
    });

    注册

    通过上面的讲述,现在执行http通信也变得简单多了。上代码

    register(data) {
    var username = data.username;
    var password = data.password;
    var body = "username=" + username + "&password=" + password + "&extra=color";
    var headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    this.http.post('http://localhost:3001/users', body, {
    headers: headers
    })
    .map(res => res.json())
    .subscribe(
    data => console.log(data),
    err => console.log(err),
    () => console.log('Register Complete')
    );
    }

    登录

    onLogin(data) {
    var username = data.username2;
    var password = data.password2;
    var body = "username=" + username + "&password=" + password + "&extra=color";
    var headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    this.http.post('http://localhost:3001/sessions/create', body, {
    headers: headers
    })
    .map(res => res.json())
    .subscribe(
    data => {
    localStorage.setItem('id_token', data.id_token), console.log(data)
    },
    err => console.log(err),
    () => console.log('Register Complete')
    );
    }

    查询

    getSecretQuote() {

    var jwt = localStorage.getItem('id_token');
    var authHeader = new Headers();
    if (jwt) {
    authHeader.append('Authorization', 'Bearer ' + jwt);
    }

    this.http.get('http://localhost:3001/api/protected/random-quote', {
    headers: authHeader
    })
    .map(res => res.text())
    .subscribe(
    data => console.log(data),
    err => console.log(err),
    () => console.log('Secret Quote Complete')
    );

    }

    在这里,执行查询前需要把本地存储中的令牌带到头部,

    var jwt = localStorage.getItem('id_token');

    这样后台就可以在查询前对令牌进行比对,如果比对成功,则返回结果。

    这样,一个简单的注册--登录--查询思路便讲解完成了

  • 相关阅读:
    Python 学习笔记 -- 列表的基本使用
    帮助你构建云服务的开源平台:openstack
    一个基于Asterisk构建的VOIP应用软件:Elastix介绍
    Asterisk项目概述
    Asterisk 代码架构概述
    云计算投入成本分析
    撕去服务器虚拟化和云计算的神秘面纱
    VOIP开源项目源码地址
    websocket技术
    JSP页面静态化总结之一使用URLRewrite实现url地址伪静态化
  • 原文地址:https://www.cnblogs.com/chendezhen/p/8436230.html
Copyright © 2020-2023  润新知