[轉]【Angular4】基礎(六):HTTP模塊

本文轉自:https://blog.csdn.net/u013451157/article/details/79519719json

版權聲明:本文爲博主原創文章,未經博主容許不得轉載。 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 等操做符。async

針對返回數據是json格式的響應對象,能夠把 Response 解析成 JavaScript 對象——只要調一下 response.json() 就能夠了,這時候咱們就能夠利用map操做符來進行處理,例如,咱們將上面的方法升級下ide

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(觀察者)是一個包含三個方法的對象post

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

this.http.post(url: string, body: any, options?: RequestOptionsArgs)
.toPromise()
.then((rsp: Response) => {
console.log(rsp)
});
1
2
3
4
5
使用 toPromise() 方法時要引入:url

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,

相關文章
相關標籤/搜索