近年来,前端开发变得越来越复杂,特别是与后台通信的方面。没有一个优秀的库来支持这一方面的开发,很多开发者只能使用浏览器自带的 XMLHttpRequest 或者 JQuery 的 ajax 方法来实现与后台的通信。这种方法会让前端开发变得混乱,不易维护。Angular 5 发布了一个新的库来处理这一方面的问题,它是 HttpClient 。
HttpClient 概述
HttpClient 是 Angular 5 中用来处理和后台交互的库。它的 API 是面向流的,它支持 JSON 格式的数据以及类型,还能处理 HTTP 请求和响应,缓存机制并支持拦截器。HttpClient 是 Angular 的一部分,所以如果你使用 Angular,HttpClient 就已经存在于你的工程中了。
HttpClient 的使用
前提:假设有一个后台服务,它有一个 GET 方法,它返回 JSON 类型的数据。
第一步,导入 HttpClient 模块。
import { HttpClientModule } from '@angular/common/http';
第二步,在 AppModule 中配置 HttpClient 模块。
@NgModule({ imports: [ BrowserModule, HttpClientModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
第三步,实现一个服务来处理请求。
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable() export class DataService { constructor(private http: HttpClient) { } getData() { return this.http.get('/api/data'); } }
getData 方法向后台发送一个 GET 请求,它请求的地址是 '/api/data' ,并返回一个 RxJS 可观察对象。RxJS 是 Angular 中用来处理异步数据流的框架。
第四步,订阅可观察对象并处理响应。
import { Component } from '@angular/core'; import { DataService } from './data.service'; @Component({ selector: 'app-root', template: ` <ul> <li *ngFor="let item of data">{{ item }}</li> </ul> `, }) export class AppComponent { data: any[]; constructor(private dataService: DataService) {} ngOnInit() { this.dataService.getData().subscribe(data => { this.data = data; }); } }
这里,我们在 AppComponent 中订阅了可观察对象,并在响应到达时更新了列表。
HttpClient 格式
HttpClient 提供了一系列的方法来处理不同的 HTTP 请求方法。这些方法分别是:
- delete
- get
- head
- jsonp
- options
- patch
- post
- put
这些方法的参数都相同,都是一个字符串类型的 url ,和一个可选的 options 对象。options 对象包含一些方法特有的参数。这个对象中的常见属性有:
- headers:请求头的配置。
- observe:指定响应类型的观察者类型。
- params:请求参数。
- reportProgress:是否报告上传或下载的进度。
- responseType:响应的类型。
- withCredentials:是否跨域请求。
HttpClient 的错误处理
当请求出错时,HttpClient 会返回一个错误信息的可观察对象。如果你希望应用程序可以处理错误,你应该订阅错误信息。你可以使用 catchError 操作符来处理这些错误。
import { Component } from '@angular/core'; import { DataService } from './data.service'; import { catchError } from 'rxjs/operators'; @Component({ selector: 'app-root', template: ` <div *ngIf="errorMessage" class="error">{{ errorMessage }}</div> <ul *ngIf="data"> <li *ngFor="let item of data">{{ item }}</li> </ul> `, }) export class AppComponent { errorMessage: string; data: any[]; constructor(private dataService: DataService) {} ngOnInit() { this.dataService.getData().pipe( catchError((error) => { this.errorMessage = '请求失败,请重试。'; return []; }) ).subscribe(data => { this.data = data; }); } }
在这个例子中,我们利用了 catchError 操作符来处理错误。当 handleError 被执行时,我们简单地将 errorMessage 赋值为一个适当的错误消息,并将 data 赋值为空数组。
HttpClient 的拦截器
在我们的应用程序中,我们可能需要在所有 HTTP 请求之前执行某些操作,例如添加身份验证信息。这正是 HTTP 拦截器的用武之地。
为了添加一个拦截器,我们首先需要定义一个拦截器类。
import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; @Injectable() export class AuthInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler) { const authToken = 'my-auth-token'; const authReq = req.clone({ headers: req.headers.set('Authorization', authToken) }); return next.handle(authReq); } }
在这个例子中,我们定义了一个 AuthInterceptor。它实现了 HttpInterceptor 接口,接口要求我们实现一个拦截方法 intercept 。intercept 方法首先检查是否有一个有效的身份验证令牌,如果有则将其添加到请求的 headers 中,同时克隆该请求。最后,返回处理函数的下一个函数的 handle 方法所返回的 observable。
这个 AuthInterceptor 类仅仅是一个简单的例子,你可以根据你的需要来添加更多的拦截器。
为了让 HttpClient 在每个请求中加入我们的拦截器,我们必须在 AppModule 中的 HttpClient 模块引入时添加拦截器类。
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { AuthInterceptor } from './auth-interceptor'; @NgModule({ imports: [ BrowserModule, HttpClientModule ], providers: [ { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true } ], bootstrap: [AppComponent] }) export class AppModule { }
在这个例子中,我们添加了一个 HTTP_INTERCEPTORS 依赖注入提供程序,并通过它来添加 AuthInterceptor 来指定我们要添加的拦截器类。multi 属性是必需的,因为我们可能有多个拦截器。
HttpClient 的缓存机制
HttpClient支持缓存响应数据,以便下一次调用该请求时,可以在不重新执行整个请求的情况下返回该响应。这可以提高应用程序的响应速度。
为了实现缓存,我们需要导入 HttpClient 的 HttpCacheService。
import { HttpCacheService } from './http-cache.service'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { CachingInterceptor } from './caching-interceptor'; @NgModule({ imports: [ BrowserModule, HttpClientModule ], providers: [ HttpCacheService, { provide: HTTP_INTERCEPTORS, useClass: CachingInterceptor, multi: true } ], bootstrap: [AppComponent] }) export class AppModule { }
然后我们需要实现一个 CachingInterceptor 类。
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { tap } from 'rxjs/operators'; import { HttpCacheService } from './http-cache.service'; @Injectable() export class CachingInterceptor implements HttpInterceptor { constructor(private cacheService: HttpCacheService) {} intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // 如果请求不可缓存,则将其传递给处理程序并返回它的结果。 if (req.method !== 'GET') { return next.handle(req); } // 如果请求在缓存中,则返回缓存响应。 const cachedResponse = this.cacheService.get(req); if (cachedResponse) { return Observable.of(cachedResponse); } // 请求网络数据,并缓存响应。 return next.handle(req) .pipe( tap(event => { if (event instanceof HttpResponse) { this.cacheService.put(req, event); } }) ); } }
CachingInterceptor 来管理我们的缓存。 在拦截器的构造函数中,我们注入了一个名为 HttpCacheService 的服务。 对于单个请求,它首先检查缓存是否包含请求的响应数据。如果缓存了该响应,则它会立即返回缓存的响应。否则,它会将请求传递给处理程序,等待网络响应,并缓存响应以供以后使用。
总结
HttpClient 是 Angular 中用来处理和后台交互的库。 它支持 JSON 数据,处理 HTTP 请求和响应,并支持拦截器。除此之外,HttpClient还支持缓存机制、异常处理等。通过学习这些内容,我们可以掌握如何顺畅地将Angular应用程序与服务器集成起来。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a6241aadd4f0e0ffed2afd