1. http

(1) 简单示例

http使用之前需要在当前导入HttpModel。然后看一个例子:

//httml:
<h3>Angular Orgs Members</h3>
<ul *ngIf="members"><li *ngFor="let member of members;"><p><img [src]="member.avatar_url" width="48" height="48"/>ID:<span>{{member.id}}</span>Name: <span>{{member.login}}</span></p></li>
</ul>
//JS:
import {Component, OnInit} from '@angular/core';
import { Http } from '@angular/http'; // (1)
import 'rxjs/add/operator/map'; // (2)interface Member {id: string;login: string;avatar_url: string;
}
@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {members: Member[];constructor(private http: Http) { } // (3)ngOnInit() {this.http.get(`https://api.github.com/orgs/angular/members?page=1&per_page=5`) // (4).map(res => res.json()) // (5).subscribe(data => {if (data) this.members = data; // (6)});}
}

上面标注序号的step的步骤说明:
  (1) 从 @angular/http 模块中导入 Http 类
  (2) 导入 RxJS 中的 map 操作符
  (3) 使用 DI 方式注入 http 服务的
  (4) 调用 http 服务的 get() 方法,设置请求地址并发送 HTTP 请求
  (5) 调用 Response 对象的 json() 方法,把响应体转成 JSON 对象
  (6) 把请求的结果,赋值给 members 属性

(2) Class file

a. Http Class

class Http {constructor(_backend: ConnectionBackend, _defaultOptions: RequestOptions)request(url: string | Request, options?: RequestOptionsArgs): Observable<Response>get(url: string, options?: RequestOptionsArgs): Observable<Response>post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>delete(url: string, options?: RequestOptionsArgs): Observable<Response>//PATCH方法是新引入的,是对PUT方法的补充,用来对已知资源进行**局部更新** (PUT 是幂等的,而 PATCH 不是幂等的。)patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>//只请求页面的首部head(url: string, options?: RequestOptionsArgs): Observable<Response>//1、获取服务器支持的HTTP请求方法;//2、用来检查服务器的性能。options(url: string, options?: RequestOptionsArgs): Observable<Response>
}

可以看到上面内置的请求方法的返回值是一个可观测的ResPonse对象(所以必须有观察者请求才会发出,也就是(1)中示例中的subscribe必须要存在),每个方法的参数均有RequestOptionsArgs。接下来我们看一下这两个类含有什么?

b. RequestOptions class

class RequestOptions {constructor(opts: RequestOptionsArgs = {})//请求方式method: RequestMethod | string | null//请求头headers: Headers | null//请求体body: any//请求的地址url: string | null//url 请求参数 (params与search都会在url的后面添加参数)params: URLSearchParamssearch: URLSearchParams//和跨域相关,表明在进行跨域访问控制请求,是否使用认证信息(cookie或者header)withCredentials: boolean | null//返回类型responseType: ResponseContentType | nullmerge(options?: RequestOptionsArgs): RequestOptions
}

举个例子:

let headersContent = new Headers();
headersContent.set('name', 'rodchen');let paramsContent = new URLSearchParams();
paramsContent.set('parmsName', 'rodchen');let searchContent = new URLSearchParams();
paramsContent.set('searName', 'rodchen-search');let requestOptions = new RequestOptions({url: 'portal/applications',method: 'Get',headers: headersContent,body: {},params: paramsContent,search: searchContent,withCredentials: true,responseType: ResponseContentType.Json
});this.http.request('portal/applications', requestOptions).subscribe(data => {console.log(data);});

然后看一下页面的发送请求:

可以看到我们设置的header,以及查询参数都已经在request中显示出来。

c. Request class

class Request extends Body {constructor(requestOptions: RequestArgs)method: RequestMethodheaders: Headersurl: string//表明在进行跨域访问控制请求,是否使用认证信息(cookie或者header)withCredentials: boolean//预期返回值的类型responseType: ResponseContentType//返回基于请求头的ContentType值detectContentType(): ContentType//返回基于请求体的ContentType值detectContentTypeFromBody(): ContentType//基于contentType返回请求体getBody(): any
}

其实可以看出内部成员和RequestOptions类似,那我们就说一下content-type.

MediaType,即是Internet Media Type,互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。

Angular中的ContentType类型如下:

export declare enum ContentType {NONE = 0,JSON = 1,FORM = 2,FORM_DATA = 3,TEXT = 4,BLOB = 5,ARRAY_BUFFER = 6,
}

这里的类型是由我们发送数据的时候决定,例如我们上面的例子是get方式,这里的结果就是本应该是0,但是由于上面添加了body属性,所以这里得到的结果是1,其他的就没有去测试了。

d. Response class

class Response extends Body {constructor(responseOptions: ResponseOptions)// "basic", "cors", "default", "error", or "opaque",默认"default"type: ResponseType//当status在200-299范围内,该值为trueok: boolean//响应的URL地址,默认为空字符串url: string//服务器返回的状态,默认为200status: number//请求的响应状态信息,默认值是"OK"statusText: string | null//非标准属性:用于表示已加载响应体的字节数bytesLoaded: number//非标准属性:表示响应体总字节数totalBytes: number//响应头对象headers: Headers | nulltoString(): string {return `Response with status: ${this.status} ${this.statusText} for URL: ${this.url}`;}
}

然后看一下上面(3)中的返回response

这里的type返回为2:

export declare enum ResponseType {Basic = 0,Cors = 1,Default = 2,Error = 3,Opaque = 4,
}

f. Body class

可以看出Resquest和Resposne都是继承与Body。

export abstract class Body {protected _body: any;json(): any { // 转化为JSON对象 - 具体应用:map(res => res.json())if (typeof this._body === 'string') {return JSON.parse(<string>this._body);}if (this._body instanceof ArrayBuffer) {return JSON.parse(this.text());}return this._body;}// 转换为Text文本text(): string { ... }// 转换为ArrayBuffer对象arrayBuffer(): ArrayBuffer { ... }// 转换为Blob对象blob(): Blob { ... }
}

看到这里会发现一个我们经常使用的方法json().

(3) http 错误处理

我们还是将上面的请求先拿下来(具体的requestOptions部分就不copy下来了)

this.http.request('portal/applications', requestOptions).subscribe(data => {console.log(data);});
}

还是先说一下http集成了Rxjs,现在this.http.request('portal/applications', requestOptions)是一个Obserable对象。由于Rx.Observable.catch(...args)用来处理异常,所以我们这里也可以使用.catch()处理异常。如下

import 'rxjs/add/operator/catch';this.http.request('portal/applications', requestOptions)
.catch(error => {console.error("error catched", error);//return Observable.throw(error);return Observable.of({description: "Error Value Emitted"})
})
.subscribe(data => {console.log(data);},error2 => {console.log(error2);}
);

这里说明两点一个是import 'rxjs/add/operator/catch',如果没有引入,catch会使用其他包里的东西。 第二个是catch的返回值必须是Observable对象,这里是将error继续抛给subscribe中的错误处理函数。

如果我在catch中没有抛出exception,那么error2处理函数就不有任何的内容输出,例如:

//注意这里的引入
import 'rxjs/add/observable/of'; this.http.request('portal/applications', requestOptions).catch(error => {console.error("error catched", error);//return Observable.throw(error);return Observable.of({description: "Error Value Emitted"})}).subscribe(data => {console.log(data);},error2 => {console.log(error2);});

然后我们再看一下结果:

现在已经没有error2错误处理函数输出的结果了。

那么这个处理的意义在于什么呢,应该是对所有的请求进行一个全局错误处理,这样我们可以在这个错误处理函数进行一些

this.http.request('portal/applications', requestOptions).catch(this.handleError).subscribe(data => {console.log(data);},error2 => {console.log(error2);});private handleError(error: any) {let errorMessage = '';if (error.message === 'Timeout has occurred') {errorMessage = 'request.timeout';} else if (error.status === 400) {errorMessage = 'tokenError, you will navigate home page after 2s!';setTimeout(function(){window.location.href = environment.guidancePageUrl;}, 2000 );} else if (error.status === 500) {errorMessage = 'service.not.connect';} else if (error.status === 401) {errorMessage = JSON.parse(error._body).message;} else if (error.status === 403) {errorMessage =  '403 : ' + error.json().message;}return Observable.throw(errorMessage);
}

这样我们就可以全面管理页面上错误信息的弹出(后台没有考虑页面上错误信息的弹出情况下)。

(4) Rxjs相关的处理

首先需要说明的一定要对应的内容引入进来,例如

import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';

a. mergeMap

mergeMap 操作符用于从内部的 Observable 对象中获取值,然后返回给父级流对象。

合并 Observable 对象 ( jsBin)

当我们发送下一个请求时,需要依赖于上一个请求的数据。即我们在需要在上一个请求的回调函数中获取相应数据,然后在发起另一个 HTTP 请求。

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';@Component({selector: 'app-root',template: `<p>{{username}} Detail Info</p>{{user | json}}`
})
export class AppComponent implements OnInit {constructor(private http: Http) { }apiUrl = 'https://jsonplaceholder.typicode.com/users';username: string = '';user: any;ngOnInit() {this.http.get(this.apiUrl).map(res => res.json()).mergeMap(users => {this.username = users[6].username;return this.http.get(`${this.apiUrl}?username=${this.username}`).map(res => res.json())}).subscribe(user => this.user = user);}
}

b.switchMap

也可以达到上面的情况

sequentialRequests() {const sequence$ = this.http.get<Course>('/courses/-KgVwEBq5wbFnjj7O8Fp.json').switchMap(course => {course.description+= ' - TEST ';return this.http.put('/courses/-KgVwEBq5wbFnjj7O8Fp.json', course)});sequence$.subscribe();
}

switchMap 操作符用于对源 Observable 对象发出的值,做映射处理。若有新的 Observable 对象出现,会在新的 Observable 对象发出新值后,退订前一个未处理完的 Observable 对象。比如实现 AutoComplete 功能,我们可以利用 switchMap 操作符,来取消无用的 Http 请求。

c. forkJoin

forkJoin 是 Rx 版本的 Promise.all(),即表示等到所有的 Observable 都完成后,才一次性返回值。

Observable.forkJoin(this.http.request('portal/applications', requestOptions), this.http.request('portal/applications', requestOptions))
.subscribe(
data => {console.log(data);
});

这里data输出的是两个请求结果的数组

2. HttpClient

http使用之前需要在当前导入HttpClientModel. 然后在构造函数中引入

constructor(private http: HttpClient) { }

(1) HttpClient请求

class HttpClient {constructor(handler: HttpHandler)request(first: string | HttpRequest<any>, url?: string, options: {...}): Observable<any>delete(url: string, options: {...}): Observable<any>get(url: string, options: {...}): Observable<any>head(url: string, options: {...}): Observable<any>jsonp<T>(url: string, callbackParam: string): Observable<T>options(url: string, options: {...}): Observable<any>patch(url: string, body: any | null, options: {...}): Observable<any>post(url: string, body: any | null, options: {...}): Observable<any>put(url: string, body: any | null, options: {...}): Observable<any>
}
//rquest请求
request(method: string, url: string, options: {body?: any;headers?: HttpHeaders | {[header: string]: string | string[];};observe?: 'body';params?: HttpParams | {[param: string]: string | string[];};reportProgress?: boolean;responseType: 'arraybuffer';withCredentials?: boolean;
}): Observable<ArrayBuffer>

然后举个例子,将上面的例子改写一下:

let headersContent = new HttpHeaders();
headersContent.set('name', 'rodchen');let paramsContent = new HttpParams();
paramsContent.set('parmsName', 'rodchen');let searchContent = new URLSearchParams();
paramsContent.set('searName', 'rodchen-search');this.http.request('GET', 'portal/applications', {headers: headersContent,params: paramsContent,responseType: 'json'
}).catch(error => {console.error("error catched", error);return Observable.throw(error);}).subscribe(data => {console.log(data);},error2 => {console.log(error2);});

其实具体的用法直接查找 官方文档就好。

至于其他的请求和request类似,只是参数缺少了一个method,例如get

get(url: string, options: {headers?: HttpHeaders | {[header: string]: string | string[];};observe?: 'body';params?: HttpParams | {[param: string]: string | string[];};reportProgress?: boolean;responseType: 'arraybuffer';withCredentials?: boolean;
}): Observable<ArrayBuffer>

(2) 新的特性

a.  默认JSON解析

在http的时候我们需要使用json函数

http.get(url).map(res => res.json()).subscribe(...)

httpClient则自己做了这个事情:

httpClient.get(url).subscribe(...)

b. 拦截器

由于没有使用这个,详情可以查看文章

c. 进度事件

进度事件可以用于跟踪文件上传和下载。详情可以查看文章

参考:

https://www.angular.cn/guide/http

https://segmentfault.com/a/1190000010116848

https://segmentfault.com/a/1190000010259536

Angular4 - http相关推荐

  1. 转《Angular4项目部署到服务器上刷新404解决办法》

    刚遇到Angular4项目npm run build 后部署到服务器可以访问,但是刷新页面会出现404的错误!转载一大神的操作 解决angular2页面刷新后报404错误办法: 配置app.modul ...

  2. Angular4.0从入门到实战打造在线竞拍网站学习笔记之四--数据绑定管道

    Angular4.0基础知识之组件 Angular4.0基础知识之路由 Angular4.0依赖注入 Angular4.0数据绑定&管道 数据绑定 数据绑定允许你将组件控制器的属性和方法与组件 ...

  3. 在Angular4中使用ng2-baidu-map详解

    一.引言 之前在Angular4使用过百度地图,记录一下踩过的坑 二.实现 1.安装 npm install angular2-baidu-map 2.在app.module.ts配置 ak key在 ...

  4. 《Angular4从入门到实战》学习笔记

    <Angular4从入门到实战>学习笔记 腾讯课堂:米斯特吴 视频讲座 二〇一九年二月十三日星期三14时14分 What Is Angular?(简介) 前端最流行的主流JavaScrip ...

  5. angular4 php,Angular4中常用管道实例详解

    通常我们需要使用管道实现对数据的格式化,Angular4中的管道和之前有了一些变化.本文主要介绍Angular4中常用管道,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧, ...

  6. 基于angular4+ng-bootstrap+bootstrap+scss的后台管理系统界面

    描述 在angular2刚才发布的不久,很多人不懂得怎么应用,直到现在也很多人不懂怎么用, 于是我在余业时间做了这么一个后台管理系统页面,希望对大家有帮助!! 从我个人的感觉来说,angular2语法 ...

  7. angular4 表单

    1.模板式表单 在html模板上控制 指令对应的实例 1.ngForm指令:标记表单,会隐式创建FormGroup类的实例,这个类代表表单数据模型,并存储表单数据: 2.ngModel指令:标记单个字 ...

  8. angular4.0微信oAuth第三方认证的正确方式

    当我们的项目运行在微信端时,用到oAuth第三方认证.问题来了,在ng4中微信认证应该放在哪里呢? 开始项目的时候,我将oAuth认证放在了每个页面模版中,发现返回历史页的时候,需要返回两次. 这个问 ...

  9. 实用比较,帮你决策到底选择Vue还是Angular4、5

    本人从Angular2时代开始用,当时全国都没什么人敢碰Angular2,我们就靠着啃它源代码中的注释,熟悉了Angular2的用法,并在实用中,还给Angular2团队提交bug. 因此,这里提供给 ...

  10. 在Visual Studio 2017中使用Asp.Net Core构建Angular4应用程序

    前言 Visual Studio 2017已经发布了很久了.做为集成了Asp.Net Core 1.1的地表最强IDE工具,越来越受.NET系的开发人员追捧. 随着Google Angular4的发布 ...

最新文章

  1. 经理让我复盘上次Redis缓存雪崩事故
  2. Spring data jpa命名规范
  3. 网易创新企业大会圆满收官  看新技术和新商业如何撞出花火
  4. 搭建hbase-0.94.26集群环境
  5. mysql常见错误解决方法_mysql常见错误解决办法
  6. Java 8 Stream 流用法及语法
  7. oracle读取blob字段的方法,如何读取Oracle的BLOB字段里的文件?
  8. 【CSDN软件工程师能力认证学习精选】Python网络编程之初识
  9. 单片机原理与接口技术试题
  10. 软件工程实验报告1-可行性分析
  11. 大二Web课程设计——张家界旅游网站设计与实现(HTML+CSS+JavaScript)
  12. 将html导出为PDF文件(为PDF加盖章)
  13. Win11系统QQ语音通话时玩游戏无声音怎么办
  14. Android 开发笔记___图像按钮__imageButton
  15. 【九度】题目1419:文献排序
  16. kettle运行spoon.sh启动图形化界面报错处理
  17. 2015出现神曲空挡期,玖月奇迹接棒筷子兄弟?
  18. 计算机vf的讲解,计算机二级《VFP》知识点讲解:查询和视图
  19. 周跃计算机四级讲义,全国计算机等级考试《信息安全工程师(四级)》复习全书【核心讲义+历年真题详解】.pdf...
  20. Camtasia教程:如何导入PowerPoint幻灯片?

热门文章

  1. Python DistributedDataParallel(DDP)训练模型
  2. 5-1 厘米换算英尺英寸 (15分) PTA
  3. Adam和学习率衰减(learning rate decay)
  4. matlab算百人同生日概率
  5. 北京ui设计工资一般多少?北京ui设计公司排名?
  6. QQ幻想杂食宠物各种前缀比较
  7. 读书笔记——计网概述
  8. 共筑信创产业生态--国产化应用如何与麒麟系统进行适配认证
  9. 毕业设计 基于JSP动漫论坛的设计与实现
  10. 我的团队人物介绍卡片布局