[转]【Angular4】基础(六):HTTP模块
本文转自:https://blog.csdn.net/u013451157/article/details/79519719
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013451157/article/details/79519719
Angular2 HTTP 模块
在 Angular4 之前的 Angular2 中,HTTP API 方法的传参数形式如下:
http.get(url: string, options?: RequestOptionsArgs): Observable<Response>
http.post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>
1
2
body 表示传递到服务器端的数据信息
options 表示头部验证信息。
两个方法都返回一个可观察对象 Observable,我们可以通过 subscribe 方法得到里面的值并作后继处理。
this.http.post(url: string, body: any, options?: RequestOptionsArgs).subscribe(function (data) {
   console.log(data)
})
1
2
3
RxJS 库
我们的服务可以返回 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);
});
1
2
3
4
5
注意,这里 .map 用到了 RxJS 库,需要导入这个库。
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
1
2
Observer(观察者)是一个包含三个方法的对象
next - 当 Observable 发送新值的时候,next 方法会被调用
error - 当 Observable 内发生错误时,error 方法会被调用
complete - 当 Observable 数据终止后,complete 方法会被调用,在调用 complete 方法之后,next 方法就不会再次被调用
Observable 对象转化为 Promise对象
  虽然 Angular 的 HTTP Client API 返回的是 Observable<Response> 类型的对象,但我们也可以把它转成 Promise<Response>。这很容易,只需要调用可观察对象 Observable< Response > 的方法 toPromise() 就能够进行转化。
this.http.post(url: string, body: any, options?: RequestOptionsArgs)
         .toPromise()
         .then((rsp: Response) => {
            console.log(rsp)
         });
1
2
3
4
5
使用 toPromise() 方法时要引入:
import 'rxjs/add/operator/toPromise';
1
Observable VS Promise
Observable	Promise
随着时间的推移发出多个值	返回单个值
可取消	不可取消
支持 map、filter、reduce 等操作符	
延迟执行,当订阅的时候才会开始执行	
- - - - - - Angular2 与 Angular4 分界线 - - - - - -
Angular4 HTTP 模块
导入新的 HTTP Module
import { HttpClientModule } from '@angular/common/http';
1
特性一 默认 JSON 解析
需要注意的是,现在 JSON 是默认的数据格式,我们不需要再进行显式的解析
http.get(url).map(res => res.json()).subscribe(...)
1
现在我们可以这样写
http.get(url).subscribe(...)
1
特性二 支持拦截器
拦截器允许我们将中间件逻辑插入管线中
请求拦截器 (Request Interceptor)
import {
  HttpRequest,
  HttpHandler,
  HttpEvent
} from '@angular/common/http';
@Injectable()
class JWTInterceptor implements HttpInterceptor {
constructor(private userService: UserService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const JWT = `Bearer ${this.userService.getToken()}`;
    req = req.clone({
      setHeaders: {
        Authorization: JWT
      }
    });
    return next.handle(req);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
如果我们想要注册新的拦截器 (interceptor),我们需要实现 HttpInterceptor 接口,然后实现该接口中的 intercept 方法。
export interface HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
}
1
2
3
需要注意的是,请求对象和响应对象必须是不可修改的 (immutable)。因此,我们在返回请求对象前,我们需要克隆原始的请求对象。
next.handle(req) 方法使用新的请求对象,调用底层的 XHR 对象,并返回响应事件流。
响应拦截器 (Response Interceptor)
@Injectable()
class JWTInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(req: HttpRequest < any > ,
    next: HttpHandler): Observable < HttpEvent < any >> {
return next.handle(req).map(event => {
        if (event instanceof HttpResponse) {
          if (event.status === 401) {
            // JWT expired, go to login
          }
        }
        return event;
      }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
响应拦截器可以通过在 next.handle(req) 返回的流对象 (即 Observable 对象) 上应用附加的 Rx 操作符来转换响应事件流对象。
接下来要应用 JWTInterceptor 响应拦截器的最后一件事是注册该拦截器,即使用 HTTP_INTERCEPTORS 作为 token,注册 multi Provider:
[{ provide: HTTP_INTERCEPTORS, useClass: JWTInterceptor, multi: true }]
1
特性三 进度事件
进度事件可以用于跟踪文件上传和下载
import {
  HttpEventType,
  HttpClient,
  HttpRequest
} from '@angular/common/http';
http.request(new HttpRequest(
  'POST',
   URL,
   body, 
  {
    reportProgress: true
  })).subscribe(event => {
if (event.type === HttpEventType.DownloadProgress) {
    // {
    // loaded:11, // Number of bytes uploaded or downloaded.
    // total :11 // Total number of bytes to upload or download
    // }
  }
if (event.type === HttpEventType.UploadProgress) {
    // {
    // loaded:11, // Number of bytes uploaded or downloaded.
    // total :11 // Total number of bytes to upload or download
    // }
  }
if (event.type === HttpEventType.Response) {
    console.log(event.body);
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
如果我们想要跟踪文件上传或下载的进度,在创建请求对象时,我们需要配置 {reportProgress: true} 参数。
此外在回调函数中,我们通过 event.type 来判断不同的事件类型,从进行相应的事件处理。
HttpEventType 枚举定义如下:
export enum HttpEventType {
  /**
   * 表示请求已经被发送
   */
  Sent,
/**
   * 已接收到上传进度事件
   */
  UploadProgress,
/**
   * 已接收到响应状态码和响应头
   */
  ResponseHeader,
/**
   * 已接收到下载进度事件
   */
  DownloadProgress,
/**
   * 已接收全部响应,包含响应体 
   */
  Response,
/**
   * 用户自定义事件,来自拦截器或后端
   */
  User,
}
--------------------- 
作者:abloume 
来源:CSDN 
原文:https://blog.csdn.net/u013451157/article/details/79519719 
版权声明:本文为博主原创文章,转载请附上博文链接!
[转]【Angular4】基础(六):HTTP模块的更多相关文章
- 【笔记】Python基础六:模块module介绍及常用模块
		
一,module模块和包的介绍 1,在Python中,一个.py文件就称之为一个模块(Module). 2,使用模块的好处? 最大的好处是大大提高了代码的可维护性 其次,编写代码不必从零开始,我们编写 ...
 - {Django基础六之ORM中的锁和事务}一 锁 二 事务
		
Django基础六之ORM中的锁和事务 本节目录 一 锁 二 事务 一 锁 行级锁 select_for_update(nowait=False, skip_locked=False) #注意必须用在 ...
 - day 71   Django基础六之ORM中的锁和事务
		
Django基础六之ORM中的锁和事务 本节目录 一 锁 二 事务 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 锁 行级锁 select_for_update(no ...
 - day  58  Django基础六之ORM中的锁和事务
		
Django基础六之ORM中的锁和事务 本节目录 一 锁 二 事务 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 锁 行级锁 select_for_update( ...
 - Django基础六之cookie和session
		
Django基础六之cookie和session 目录 Django基础六之cookie和session 1. cookie和session介绍 1.1 cookie 简介 1.2 cookie的缺陷 ...
 - Bootstrap<基础六> 表单
		
Bootstrap 通过一些简单的 HTML 标签和扩展的类即可创建出不同样式的表单. 表单布局 Bootstrap 提供了下列类型的表单布局: 垂直表单(默认) 内联表单 水平表单 垂直或基本表单 ...
 - C#_02.15_基础六_.NET类
		
C#_02.15_基础六_.NET类 一.类继承是一个类在另一个类的基础上进行的扩展. 继承的子类拥有父类的全部成员.索引子类拥有本身的全部成员以及父类的全部成员. 可以对基类成员进行隐藏,如果必须的 ...
 - 十八. Python基础(18)常用模块
		
十八. Python基础(18)常用模块 1 ● 常用模块及其用途 collections模块: 一些扩展的数据类型→Counter, deque, defaultdict, namedtuple, ...
 - Python学习系列(六)(模块)
		
Python学习系列(六)(模块) Python学习系列(五)(文件操作及其字典) 一,模块的基本介绍 1,import引入其他标准模块 标准库:Python标准安装包里的模块. 引入模块的几种方式: ...
 - Python基础-包与模块
		
Python基础-包与模块 写在前面 如非特别说明,下文均基于Python3 摘要 为重用以及更好的维护代码,Python使用了模块与包:一个Python文件就是一个模块,包是组织模块的特殊目录(包含 ...
 
随机推荐
- numpy、pandas
			
numpy: 仨属性:ndim-维度个数:shape-维度大小:dtype-数据类型. numpy和pandas各def的axis缺省为0,作用于列,除DataFrame的.sort_index()和 ...
 - Linux上搭建Hadoop集群
			
本文将为初学者的搭建简单的伪分布式集群,将搭建一台虚拟机,用于学习Hadoop 工具:vm虚拟机,centOS7,jdk-8,Hadoop2.7,xftp,xshell 用户:在虚拟机中创建一个had ...
 - Mybatis的JDBC提交设置/关闭mysql自动提交------关于mysql自动提交引发的惨剧
			
学习Mybatis时提到了JDBC方式需要自己手动提交事务,如果不加session.commit会导致数据库的数据无法正常插入(程序本身又不给你报错,还装出一副我已经插入成功的样子) SqlSessi ...
 - JavaScript自定义鼠标右键菜单
			
下面为JavaScript代码 window.onload = function () { //好友列表 var f = 0; //判断指定id的元素在页面中是否存在 if (document.get ...
 - shell指令(一)
			
ubuntu桌面窗口下进入shell窗口:Ctrl + Alt + F2~F6: 退出shell窗口:Ctrl + Alt + F7:从UI中进入UI命令窗口,Ctrl + Alt +T shell ...
 - Chapter 1: Plug-in programing from past to the future
			
It is the best time. Although the internal API of Android not allowed to be modified by google play, ...
 - Spark基础-scala学习(五、集合)
			
集合 scala的集合体系结构 List LinkedList Set 集合的函数式编程 函数式编程综合案例:统计多个文本内的单词总数 scala的集合体系结构 scala中的集合体系主要包括:Ite ...
 - linux下 几个常用makefile模板,亲测可用
			
一 生成动态链接库的模板: ####################### # Makefile ####################### # compile and lib parameter ...
 - setInterval()与setTimeout()的区别
			
setInterval()-一旦被开启就会不断的执行,使用clearInterval()清除后将不再执行 setTimeout()-又称为一次定时器,定时器开启后只执行一次将不会接着执行,使用clea ...
 - swiper在vue项目中的循环轮播bug以及点击事件
			
一般的,如果是静态数据(本地数据),可以直接在mounted生命周期中初始化,循环轮播.自动播放都比较正常. 但是,如果是动态从后台获取数据的话,采用上述方法会发现,轮播图无法自动播放,也无法拖拽. ...