详解使用angular的HttpClient搭配rxjs

发布时间 - 2026-01-11 03:03:27    点击率:

一、原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,所有请求都会实现添加配置好的头部信息。

响应预处理

请求得到结果后,往往需要对结果进行一些判断,比如某些错误是请求本身的错误,这些错误会直接抛出到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()的时候,才会真正执行整个请求,并在三种回调中体现。

对于rxjs的学习强烈推荐 Rxjs 5 ultimate 简直胜看十篇博。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# angular  # rxjs  # 搭配rxjs  # angular.js4使用 RxJS 处理多个 Http 请求  # 详细介绍RxJS在Angular中的应用  # Angular搜索场景中使用rxjs的操作符处理思路  # Angular5升级RxJS到5.5.3报错:EmptyError: no elements in   # 如何用RxJS实现Redux Form  # 关于RxJS Subject的学习笔记  # 使用RxJS更优雅地进行定时请求详析  # 回调  # 可选  # 拦截器  # 文件上传  # 的是  # 并在  # 自己的  # 是在  # 相关内容  # 都在  # 第一个  # 都能  # 则是  # 才会  # 可以用  # 一脸  # 这类  # 要做  # 第二个  # 比较好 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 高防服务器:AI智能防御DDoS攻击与数据安全保障  如何快速登录WAP自助建站平台?  如何在IIS中配置站点IP、端口及主机头?  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  如何快速搭建FTP站点实现文件共享?  Laravel storage目录权限问题_Laravel文件写入权限设置  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】  Laravel如何使用Blade组件和插槽?(Component代码示例)  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  Laravel如何处理CORS跨域请求?(配置示例)  如何在Windows 2008云服务器安全搭建网站?  如何在阿里云服务器自主搭建网站?  如何快速搭建虚拟主机网站?新手必看指南  如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程  制作旅游网站html,怎样注册旅游网站?  如何在IIS7上新建站点并设置安全权限?  Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】  CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】  如何打造高效商业网站?建站目的决定转化率  Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  LinuxCD持续部署教程_自动发布与回滚机制  网站页面设计需要考虑到这些问题  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  Laravel事件和监听器如何实现_Laravel Events & Listeners解耦应用的实战教程  Claude怎样写约束型提示词_Claude约束提示词写法【教程】  *服务器网站为何频现安全漏洞?  深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?  高端企业智能建站程序:SEO优化与响应式模板定制开发  Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境  IOS倒计时设置UIButton标题title的抖动问题  Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置  WordPress 子目录安装中正确处理脚本路径的完整指南  如何确保西部建站助手FTP传输的安全性?  Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧  Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面  Java垃圾回收器的方法和原理总结  Python进程池调度策略_任务分发说明【指导】  怎样使用JSON进行数据交换_它有什么限制  如何正确选择百度移动适配建站域名?  如何续费美橙建站之星域名及服务?  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  如何用y主机助手快速搭建网站?  香港服务器网站卡顿?如何解决网络延迟与负载问题?  Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置  手机软键盘弹出时影响布局的解决方法  HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  Linux系统命令中tree命令详解