what?ngify 比 axios 更好用,更强大?
文章目录
- 前言
- 一、什么是ngify?
- 二、npm安装
- 三、发起请求
- 3.1 获取 JSON 数据
- 3.2 获取其他类型的数据
- 3.3 改变服务器状态
- 3.4 设置 URL 参数
- 3.5 设置请求标头
- 3.6 与服务器响应事件交互
- 3.7 接收原始进度事件
- 3.8 处理请求失败
- 3.9 Http Observables
- 四、更换 HTTP 请求实现
- 五、XSRF/CSRF 防护
- 六、全局配置
- 七、基本用法
- 八、拦截请求和响应
- 九、测试请求
- 十、支持
前言
这篇文章主要介绍了 @ngify/http 这一响应式 HTTP 客户端,包括其与 axios 的关联、功能特点、基本用法(如获取不同类型数据、设置参数和标头等)、拦截器的使用、更换请求实现、防护机制、全局配置及测试请求等,还对比了它与其他库的差异,强调了其稳定性和便捷性。

一、什么是ngify?
在前端开发中,使用最广泛的 HTTP 客户端为 axios,它是一个用于浏览器和 Node.js 的、基于 Promise 的 HTTP 客户端。
axios 的前身其实是 AngularJS 的 $http 服务。axios 深受 AngularJS 中提供的 $http 服务的启发,将 $http 服务从 AngularJS 中剥离,提供一个独立的服务,以便在 AngularJS 之外使用。
注:AngularJS 特指 AngularJS v1,而非 Angular 2+。
Angular2+ 抛弃了原有的 $http 服务,转而与 RxJS 深度集成,打造了一个更加先进、现代化的响应式 HTTP 客户端。这个新的客户端充分利用了 RxJS 的强大功能,提供了更灵活、更易于理解的异步操作方式。然而,由于其与 Angular 的依赖注入和 SSR 功能紧密耦合,使得它无法直接应用于 Angular 生态之外。
@ngify/http 是一个基于 RxJS 的响应式 HTTP 客户端,提供了与 Angular HttpClient 高度一致的 API,主要包含以下功能:
- 请求类型化响应对象的能力。
- 简化的错误处理。
- 请求和响应的拦截机制。
- 轻松处理请求超时、重试、并发、缓存等等。
- 支持多种平台:Web、Node.js、微信小程序、uni-app、taro 等等。
@ngify/http 的目标与 axios 一致:提供一个独立的 HTTP 服务,以便在 Angular2+ 之外使用。
💯无需担心 @ngify/http 的稳定性,@ngify/http 采用了与 Angular HttpClient 相同的严格单元测试,确保了其代码质量和可靠性,在各种场景下保持足够的稳定性。
二、npm安装
npm install @ngify/http
三、发起请求
HttpClient 具有与用于发出请求的不同 HTTP 动词相对应的方法,这些方法既可以加载数据,也可以在服务器上应用变更。每个方法都返回一个 RxJS Observable,订阅后会发送请求,然后在服务器响应时发出结果。
由 HttpClient 创建的 Observable 可以被订阅任意多次,并且每次订阅都会发出一个新的后端请求。
通过传递给请求方法的选项对象,可以调整请求的各种属性和返回的响应类型。
3.1 获取 JSON 数据
从后端获取数据通常需要使用 HttpClient.get() 方法发出 GET 请求。此方法采用两个参数:要从中获取的字符串端点 URL,以及用于配置请求的可选选项对象。
例如,要使用 HttpClient.get() 方法从假设的 API 获取配置数据:
http.get<Config>('/api/config').subscribe(config => {// process the configuration.
});
请注意泛型类型参数,它指定服务器返回的数据的类型为 Config 。该参数是可选的,如果省略它,则返回的数据将具有 any 类型。
🎯 注意: 如果数据具有未知形状的类型,那么更安全的方法是使用 unknown 作为响应类型。
请求方法的通用类型是关于服务器返回的数据的类型断言。 HttpClient 不会验证实际返回数据是否与该类型匹配。
3.2 获取其他类型的数据
默认情况下, HttpClient 假定服务器将返回 JSON 数据。与非 JSON API 交互时,您可以告诉 HttpClient 在发出请求时期望并返回什么响应类型。这是通过 responseType 选项完成的。
| Response type | Returned response type |
|---|---|
| ‘json’ (默认) | 给定泛型类型的 JSON 数据 |
| ‘text’ | 字符串文本 |
| ‘blob’ | Blob 实例 |
| ‘arraybuffer’ | 包含原始响应字节的 ArrayBuffer |
例如,您可以要求 HttpClient 将 .jpeg 图像的原始字节下载到 ArrayBuffer 中:
http.get('/images/dog.jpg', { responseType: 'arraybuffer' }).subscribe(buffer => {console.log('The image is ' + buffer.byteLength + ' bytes large');
});
3.3 改变服务器状态
执行修改的服务器 API 通常需要发出 POST 请求,并在请求正文中指定新状态或要进行的更改。
HttpClient.post() 方法的行为与 get() 类似,只是第二位参数变为 body 参数:
http.post<Config>('/api/config', newConfig).subscribe(config => {console.log('Updated config:', config);
});
可以提供许多不同类型的值作为请求的 body,并且 HttpClient 将相应地序列化它们:
| Body | typeSerialization as |
|---|---|
| string | 纯文本 |
| number、boolean、Array 或 object | JSON 字符串 |
| ArrayBuffer | 来自 buffer 的原始数据 |
| Blob | 具有 Blob 内容类型的原始数据 |
| FormData | multipart/form-data 表单数据 |
| HttpParams 或 URLSearchParams | application/x-www-form-urlencoded 格式化字符串 |
3.4 设置 URL 参数
使用 params 选项指定应包含在请求 URL 中的请求参数。
传递字面量对象是配置 URL 参数的最简单方法:
http.get('/api/config', {params: { filter: 'all' },
}).subscribe(config => {// ...
});http.post('/api/config', body, {params: { filter: 'all' },
}).subscribe(config => {// ...
});
或者,如果您需要对参数的构造或序列化进行更多控制,则可以传递 HttpParams 的实例。
🎯注意: HttpParams 的实例是不可变的,不能直接更改。相反,诸如 append() 之类的可变方法会返回应用了变更的 HttpParams 的新实例。
const baseParams = new HttpParams().set('filter', 'all');http.get('/api/config', {params: baseParams.set('details', 'enabled')
}).subscribe(config => {// ...
});http.post('/api/config', body, {params: baseParams.set('details', 'enabled')
}).subscribe(config => {// ...
});
您可以使用自定义 HttpParameterCodec 实例化 HttpParams(构造方法中的第二个参数),该自定义 HttpParameterCodec确定HttpClient` 如何将参数编码到 URL 中。
3.5 设置请求标头
使用 headers 选项指定应包含在请求中的请求标头。
传递字面量对象是配置请求标头的最简单方法:
http.get('/api/config', {headers: {'X-Debug-Level': 'verbose',}
}).subscribe(config => {// ...
});
或者,如果您需要对标头的构造进行更多控制,请传递 HttpHeaders 的实例。
🎯注意: HttpHeaders 的实例是不可变的,不能直接更改。相反,诸如 append() 之类的可变方法会返回应用了变更的 HttpHeaders 的新实例。
const baseHeaders = new HttpHeaders().set('X-Debug-Level', 'minimal');http.get<Config>('/api/config', {headers: baseHeaders.set('X-Debug-Level', 'verbose'),
}).subscribe(config => {// ...
});
3.6 与服务器响应事件交互
为了方便起见,HttpClient 默认返回服务器返回的数据的 Observable(body)。有时需要检查实际响应,例如检索特定的响应标头。
要访问整个响应,请将 observe 选项设置为 'response':
http.get<Config>('/api/config', { observe: 'response' }).subscribe(res => {console.log('Response status:', res.status);console.log('Body:', res.body);
});
3.7 接收原始进度事件
除了响应正文或响应对象之外,HttpClient 还可以返回与请求生命周期中的特定时刻相对应的原始事件流。这些事件包括何时发送请求、何时返回响应标头以及何时完成正文。这些事件还可以包括报告大型请求或响应正文的上传和下载状态的进度事件。
默认情况下,进度事件处于禁用状态(因为它们会产生性能成本),但可以使用 reportProgress 选项来启用。
🎯注意:
HttpClient的fetch实现不支持报告上传进度事件。
要观察事件流,请将 observe 选项设置为 'events':
http.post('/api/upload', myData, {reportProgress: true,observe: 'events',
}).subscribe(event => {switch (event.type) {case HttpEventType.UploadProgress:console.log('Uploaded ' + event.loaded + ' out of ' + event.total + ' bytes');break;case HttpEventType.Response:console.log('Finished uploading!');break;}
});
事件流中报告的每个 HttpEvent 都有一个 type 来区分事件所代表的内容:

3.8 处理请求失败
HTTP 请求失败有两种情况:
- 网络或连接错误可能会阻止请求到达后端服务器。
- 后端可以收到请求但无法处理,并返回错误响应。
HttpClient 在 HttpErrorResponse 中捕获这两种错误,并通过 Observable 的错误通道返回该错误。网络错误的 status 代码为 0,error 是 ProgressEvent 的实例。
后端错误具有后端返回的失败 status 代码,以及错误响应 error。检查响应以确定错误的原因以及处理错误的适当操作。
RxJS 提供了多个可用于错误处理的运算符。
您可以使用 catchError 运算符将错误响应转换为 UI 的值。该值可以告诉 UI 显示错误页面或值,并在必要时捕获错误原因。
有时,诸如网络中断之类的暂时性错误可能会导致请求意外失败,只需重试请求即可使其成功。RxJS 提供了几个重试运算符,它们在某些条件下自动重新订阅失败的 Observable。例如,retry() 运算符将自动尝试重新订阅指定的次数。
3.9 Http Observables
HttpClient 上的每个请求方法都会构造并返回所请求响应类型的 Observable。使用 HttpClient 时,了解这些 Observable 的工作原理非常重要。
HttpClient 生成 RxJS 所谓的 “冷” Observable,这意味着在订阅 Observable之前不会发生任何实际请求。只有这样,请求才真正发送到服务器。多次订阅同一个 Observable会触发多个后端请求。每个订阅都是独立的。
一旦响应返回,来自 HttpClient 的 Observable通常会自动完成(尽管拦截器会影响这一点)。
由于自动完成,如果不清理 HttpClient订阅,通常不存在内存泄漏的风险。
四、更换 HTTP 请求实现
@ngify/http 内置了以下 HTTP 请求实现:
| HTTP请求实现 | 包 | 描述 |
|---|---|---|
| withXhr | @ngify/http | 使用 XMLHttpRequest 进行 HTTP 请求 |
| withFetch | @ngify/http | 使用 Fetch API 进行 HTTP 请求 |
| withWx | @ngify/http-wx | 在 微信小程序 中进行 HTTP 请求 |
| withTaro | @ngify/http-taro | 在 Taro 中进行 HTTP 请求 |
| withUni | @ngify/http-uni | 在 Uni-app 中进行 HTTP 请求 |
HttpClient 默认使用 withXhr,您可以自行切换到其他实现:
import { withXhr, withFetch } from '@ngify/http';
import { withWx } from '@ngify/http-wx';const xhrHttp = new HttpClient(withXhr()
);
const fetchHttp = new HttpClient(withFetch()
);
const wxHttp = new HttpClient(withWx()
);
你还可使用自定义的 HttpBackend 实现:
// 需要实现 HttpBackend 接口
class CustomHttpBackend implements HttpBackend {handle(request: HttpRequest<any>): Observable<HttpEvent<any>> {// ...}
}const customHttp = new HttpClient({kind: HttpFeatureKind.Backend,value: new CustomHttpBackend()}
);
五、XSRF/CSRF 防护
HttpClient 支持用于防止 XSRF 攻击的通用机制。执行 HTTP 请求时,拦截器从 cookie 中读取令牌(默认为 XSRF-TOKEN),并将其设置为 HTTP 标头(默认为 X-XSRF-TOKEN)。
由于只有在您的域上运行的代码才能读取 cookie,因此后端可以确定 HTTP 请求来自您的客户端应用程序而不是攻击者。
要启用 XSRF 防护,请在 HttpClient 实例化时或在 setupHttpClient 中传递 withXsrfProtection():
const http = new HttpClient(withXsrfProtection()
);
如果您的后端服务对 XSRF 令牌 cookie 或标头使用不同的名称,请自定义 cookie 名称与标头名称:
withXsrfProtection({cookieName: 'CUSTOM_XSRF_TOKEN',headerName: 'X-Custom-Xsrf-Header',
});
默认情况下,拦截器会在除 GET/HEAD 外的所有请求(例如 POST)上将此标头发送到相对 URL,但不会在具有绝对 URL 的请求上发送此标头。
为什么不保护 GET 请求?
仅对于可以更改后端状态的请求才需要 CSRF 保护。就其本质而言,CSRF 攻击跨越域边界,并且 Web 的同源策略将阻止攻击页面检索经过身份验证的 GET 请求的结果。
为了利用这一点,您的服务器需要在页面加载或第一个 GET 请求时在名为 XSRF-TOKEN 的 cookie 中设置一个令牌。
在后续请求中,服务器可以验证 cookie 是否与 X-XSRF-TOKEN HTTP 标头匹配,因此确保只有在您的域上运行的代码才能发送请求。
令牌对于每个用户必须是唯一的,并且必须可由服务器验证;这可以防止客户端创建自己的令牌。
HttpClient 仅支持 XSRF 保护方案的客户端部分
您的后端服务必须配置为为您的页面设置 cookie,并验证标头是否存在于所有符合条件的请求中。如果不这样做,HttpClient 的 XSRF 保护就会失效。
六、全局配置
您可以使用 setupHttpClient 函数进行全局配置:
setupHttpClient(withFetch(),withXsrfProtection(),
);
七、基本用法
待续
八、拦截请求和响应
请移步:ngify 拦截请求和响应
九、测试请求
参考 angular.dev/guide/http/…
十、支持
对 @ngify/http 感兴趣?为该项目点星⭐!@ngify/http

相关文章:
what?ngify 比 axios 更好用,更强大?
文章目录 前言一、什么是ngify?二、npm安装三、发起请求3.1 获取 JSON 数据3.2 获取其他类型的数据3.3 改变服务器状态3.4 设置 URL 参数3.5 设置请求标头3.6 与服务器响应事件交互3.7 接收原始进度事件3.8 处理请求失败3.9 Http Observables 四、更换 HTTP 请求实现…...
安装虚拟机VMware遇到的问题
问题1:进入如下界面,不知道如何操作 解决办法 键盘⬇️,选择“Reset the system”回车 问题2:系统存放位置我给放在了VMware安装目录,具体D:\software\VMware\Windows安装不行 解决办法:D:\software\virt…...
通过ESP32和INMP441麦克风模块实现音频数据传递
在现代物联网(IoT)项目中,音频数据的采集与传输成为了一个热门的应用领域。通过结合ESP32开发板和INMP441麦克风模块,我们可以实现一个低成本、高效率的音频数据传输系统。本文将详细介绍如何使用这两种硬件组件来构建和测试音频传…...
Vue中nextTick实现原理
源码实现思路(面试高分回答) 面试官问我 Vue 的 nextTick 原理是怎么实现的,我这样回答: 在调用 this.$nextTick(cb) 之前: 存在一个 callbacks 数组,用于存放所有的 cb 回调函数。存在一个 flushCallbac…...
数据仓库基础常见面试题
1.数据仓库是什么 数据仓库(Data Warehouse)是一个面向主题的、集成的、非易失的、随时间变化的数据集合,用于支持企业的管理决策。它不同于传统的操作型数据库,后者主要用于处理日常业务交易和实时查询,而数据仓库…...
Java设计模式——单例模式(特性、各种实现、懒汉式、饿汉式、内部类实现、枚举方式、双重校验+锁)
文章目录 单例模式1️⃣特性💪单例模式的类型与实现:类型懒汉式实现(线程不安全)懒汉式实现(线程安全)双重锁校验懒汉式(线程安全)饿汉式实现(线程安全)使用类的内部类实现⭐枚举方式实现单例(推荐)👍 单例…...
数字普惠金融对新质生产力的影响研究(2015-2023年)
基于2015—2023年中国制造业上市公司数据,探讨了数字普惠金融对制造业企业新质生产力的影响及作用机理。研究发现,数字普惠金融有助于促进制造业企业新质生产力的发展,尤其是在数字普惠金融的使用深度较大的情况下,其对新质生产力…...
国产编辑器EverEdit - 扩展脚本:新建同类型文件(避免编程学习者反复新建保存练习文件)
1 扩展脚本:在当前文件目录下新建同类型文件 1.1 应用场景 用户在进行编程语言学习时,比如:Python,经常做完一个小练习后,又需要新建一个文件,在新建文件的时候,不但要选择文件类型,…...
jupyter notebook练手项目:线性回归——学习时间与成绩的关系
线性回归——学习时间与学习成绩的关系 第1步:导入工具库 pandas——数据分析库,提供了数据结构(如DataFrame和Series)和数据操作方法,方便对数据集进行读取、清洗、转换等操作。 matplotlib——绘图库,p…...
dockerfile2.0
dockerfile实现lnmp nginx centos7 mysql centos7 php centos7 自定义镜像来实现整个架构 cd /opt mkdir nginx mysql php cd nginx 拖入nginx和wordpress vim Dockerfile vim nginx.conf ↓ worker_processes 1; events {worker_connections 1024; } http {include …...
【spring mvc】文件上传、下载
文件上传,存储至本地目录中 一、代码1、工具类(敏感后缀过滤)2、文件上传,存储至本地3、文件下载 二、效果演示1、上传1.1、postMan 请求1.2、上传效果 2、下载2.1、下载效果 一、代码 1、工具类(敏感后缀过滤&#x…...
FPGA工程师成长四阶段
朋友,你有入行三年、五年、十年的职业规划吗?你知道你所做的岗位未来该如何成长吗? FPGA行业的发展近几年是蓬勃发展,有越来越多的人才想要或已经踏进了FPGA行业的大门。很多同学在入行FPGA之前,都会抱着满腹对职业发…...
java fastjson2 解析JSON用法解析
Fastjson2 是 Fastjson 的升级版本,提供了更好的性能和扩展性,同时也在 API 和功能上做了很多改进。使用 Fastjson2 解析 JSON 数据非常简单,支持多种方式来解析 JSON 字符串、嵌套 JSON 对象和数组、以及转换成 Java 对象。下面详细介绍 Fas…...
计算机视觉算法实战——步态识别(主页有源码)
✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ 1. 步态识别简介✨✨ 步态识别(Gait Recognition)是计算机视觉领域中的一个…...
LabVIEW水位监控系统
LabVIEW开发智能水位监控系统通过集成先进的传感技术与控制算法,为工业液体存储提供精确的水位调控,保证了生产过程的连续性与安全性。 项目背景 在化工和饮料生产等行业中,水位控制的准确性对保证生产安全和提高产品质量至关重要。传统的水…...
网络层协议-----IP协议
目录 1.认识IP地址 2.IP地址的分类 3.子网划分 4.公网IP和私网IP 5.IP协议 6.如何解决IP地址不够用 1.认识IP地址 IP 地址(Internet Protocol Address)是指互联网协议地址。 它是分配给连接到互联网的设备(如计算机、服务器、智能手机…...
计算机网络八股文学习笔记
总结来自于javaguide,本文章仅供个人学习复习 javaguide计算机网络八股 文章目录 计算机网络基础网络分层模型OSI七层模型TCP/IP四层模型 HTTP从输入URL到页面展示到底发生了什么?(非常重要)HTTP状态码HTTP Header中常见的字段有哪些?HTTP和HTTPS有什么区别?(重要)HTTP/1.0和…...
IntelliJ IDEA中Maven项目的配置、创建与导入全攻略
大家好,我是袁庭新。 IntelliJ IDEA是当前最流行的Java IDE(集成开发环境)之一,也是业界公认最好用的Java开发工具之一。IntelliJ IDEA支持Maven的全部功能,通过它我们可以很轻松地实现创建Maven项目、导入Maven项目、…...
如何在Jupyter中快速切换Anaconda里不同的虚拟环境
目录 介绍 操作步骤 1. 选择环境,安装内核 2. 注册内核 3. 完工。 视频教程 介绍 很多网友在使用Jupyter的时候会遇到各种各样的问题,其中一个比较麻烦的问题就是我在Anaconda有多个Python的环境里面,如何让jupyter快速切换不同的Pyt…...
stack和queue专题
文章目录 stack最小栈题目解析代码 栈的压入弹出序列题目解析代码 queue二叉树的层序遍历题目解析代码 stack stack和queue都是空间适配器 最小栈 最小栈的题目链接 题目解析 minst是空就进栈,或者是val < minst.top()就进栈 代码 class MinStack { public:M…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
