详解使用angular的HttpClient搭配rxjs

一、原Http使用总结

使用方法

1.在根模块或核心模块引入HttpModule

即在AppModule或CoreModule中引入HttpModule:

import { HttpModule } from '@angular/http'; @NgModule({ import: [ HttpModule ] // ... }) AppModule {}

2.在使用的地方注入Http服务

import { Http } from '@angular/http'; // ... constructor( private http: Http ) {} ngOnInit() { this.http.get(`url`).subscribe((res) => { // 成功回调 }, (err) => { // 失败回调 }); } // ...

3.使用可选参数

若想在请求中添加特定的头部或者身体,就需要配置请求的可选参数:

import { Http, Header } from '@angular/http'; // ... this.http.delete(`url`, {headers: new Header(), body: { } }).subscribe(...); // ...

缺陷

已知缺陷之一为不支持文件传输,如果想要写一个文件上传的客户端,就只能使用JS原生的XMLHttpRequest对象,然后自己封装上rxjs得到一个较通用的文件上传服务,可以参考 ngx-uploader。

另一个不能算缺陷的缺陷是Http请求得到的响应结果必须手动执行json()以得到json格式的结果。

二、改用HttpClient

HttpClient能力在angular 4.3版本开始引入在@angular/common/http中

使用方法

基本使用方法与原Http服务类似,先引入HttpClientModule,然后注入HttpClient服务使用:

import { HttpClientModule } from '@angular/common/http'; // ... @NgModule({ import: [ HttpClientModule ] }) // ...

import { HttpClient } from '@angular/common/http'; // ... constructor( private http: HttpClient ) {} // ... this.http.get('url').subscribe((res) => { // 成功回调 }, (err) => { // 失败回调 }); // ...

添加额外头部等信息的话类似原Http服务,引入相关的变量后填入第二个可选参数即可。

改进与加强

1.支持更多类型的请求,比如更改可选参数的responseType值可改为直接请求text内容
2.不再需要手动调用json()来将结果转为json格式,订阅到的结果已经是body且转为了json(请求text的话直接就是text内容)。
3.支持监听请求进度(可用于文件上传)。
4.添加了拦截器能力,用于预设请求规则和响应预处理。

缺陷

已知的一个小缺陷是,delete请求不能再添加body作为可选参数了,这个略尴尬,难道批量删除也得乖乖把参数拼到url中。。。

三、拦截器

本文暂不讨论文件上传以及请求进度的监听能力,可以查看官网的,本文主要来讲拦截器的简单使用。

给应用注入拦截器的效果是,所有的HttpClient发起的请求都将执行这个拦截器,类似Node中的中间件。且无论是请求之前的预处理还是得到响应后的预处理都能做到。

笔者想到的第一个用处就是不再需要写一个自己的Http服务来代执行angular的Http服务了,以往如果想要给应用的所有请求都添加比如认证功能的请求头的话,比较好的办法就是自己建立一个MyHttp服务来代为调用Http方法,并在请求回调中添加统一的结果处理。

拦截器属于特殊服务,实现了HttpInterceptor类:

import {Injectable} from '@angular/core'; import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http'; @Injectable() export class MyInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req); } }

编辑好拦截器后需要注入到根模块中:

import {NgModule} from '@angular/core'; import {HTTP_INTERCEPTORS} from '@angular/common/http'; @NgModule({ providers: [{ provide: HTTP_INTERCEPTORS, useClass: MyInterceptor, multi: true, }], }) export class AppModule {}

预处理请求

所有工作都在拦截器中的intercept方法中进行,如果要给所有请求加一个认证头部,可以操作其中的req参数,注意req参数为只读的,必须执行其clone方法得到副本来操作,处理完的副本通过next参数发射出去即可:

public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { let authInfo = {token: 'testtoken', admin: 'testadmin'}; const authReq = req.clone({ headers: req.headers .set('Authorization', authInfo.token || '') .set('Admin', authInfo.admin || '') .set('Content-Type', 'application/json;charset=UTF-8') }); return next.handle(authReq); }

这样实际使用请求时可以直接使用HttpClient,所有请求都会实现添加配置好的头部信息。

响应预处理

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wygjfs.html