小编给大家分享一下如何使用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, next: HttpHandler): Observable > { 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, next: HttpHandler): Observable > { 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,所有请求都会实现添加配置好的头部信息。
响应预处理
请求得到结果后,往往需要对结果进行一些判断,比如某些错误是请求本身的错误,这些错误会直接抛出到rxjs的error流中,某些请求本身是成功的,但是是属于一些服务器逻辑给出的错误,这类错误如果不做处理是会被认为是成功的请求而直接next到成功回调的,这会导致最终订阅请求时,错误的回调要做错误处理,成功回调中也存在需要做错误处理,感觉成功还得分为成功地成功和成功地失败,很尴尬:
someReq().subscribe((res) => { if (res.state) { // 真正成功 } else { // 还是失败 } }, (err) => { // 失败 });
通过拦截器可以对请求结果进行重新整理,保证成功回调必然成功,失败回调必然失败:
return next.handle(authReq).map((event) => { if (event instanceof HttpResponse) { switch (event.status) { case 200: if (event.body['state']) { let newEvent = event.clone({body: event.body['data']}); return newEvent; } else { throw event.body['msg']; } case 401: this.storage.remove('auth_token'); this.router.navigate(['/login']); default: throw `【${event.status}】【${event.statusText}】`; } } return event; });
响应预处理的一句话总结就是操作intercept方法返回的next.handle(req),使用rxjs的map操作符进行映射。
四、搭配rxjs
rxjs是angular严重依赖的一个大坑,初次接触会被其创建和订阅这种使用方式搭配一大堆眼花缭乱的操作符弄得一脸懵逼。
创建-订阅的请求方式
原Http和新的HttpClient两个服务流严重依赖了rxjs,请求的发起返回的是一个Observable对象,其定义好后并不会直接发起请求,真正发起请求是在执行其subscribe方法的时候,此方法接收三个参数,分别是成功回调、失败回调和完成回调。
Promise的套路是请求在定义(调用)的时候就发起了,然后迎来的是一连串的then()和catch()。可以从catch中resolve到then,或者从then中reject到catch。
rxjs的套路则是先创建出一个观察者对象(Observable),可以用许多操作符定义许多规则,比如个人感觉很接近then的map操作符,以及接近catch的catch操作符。可以从map操作符中直接throw到错误回调,或者在catch操作符中捕捉错误并返回新的成功的流。这一切都不会触发这个请求,只有最终subscribe()的时候,才会真正执行整个请求,并在三种回调中体现。
以上是“如何使用angular的HttpClient搭配rxjs”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联成都网站设计公司行业资讯频道!
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
本文题目:如何使用angular的HttpClient搭配rxjs-创新互联
文章URL:http://lswzjz.com/article/cojeie.html