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 的、基于 PromiseHTTP 客户端。
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 typeReturned 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 将相应地序列化它们:

BodytypeSerialization as
string纯文本
number、boolean、Array 或 objectJSON 字符串
ArrayBuffer来自 buffer 的原始数据
Blob具有 Blob 内容类型的原始数据
FormDatamultipart/form-data 表单数据
HttpParams 或 URLSearchParamsapplication/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 选项来启用。

🎯注意:HttpClientfetch 实现不支持报告上传进度事件。

要观察事件流,请将 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 请求失败有两种情况:

  • 网络或连接错误可能会阻止请求到达后端服务器。
  • 后端可以收到请求但无法处理,并返回错误响应。

HttpClientHttpErrorResponse 中捕获这两种错误,并通过 Observable 的错误通道返回该错误。网络错误的 status 代码为 0,errorProgressEvent 的实例。
后端错误具有后端返回的失败 status 代码,以及错误响应 error。检查响应以确定错误的原因以及处理错误的适当操作。

RxJS 提供了多个可用于错误处理的运算符。

您可以使用 catchError 运算符将错误响应转换为 UI 的值。该值可以告诉 UI 显示错误页面或值,并在必要时捕获错误原因。

有时,诸如网络中断之类的暂时性错误可能会导致请求意外失败,只需重试请求即可使其成功。RxJS 提供了几个重试运算符,它们在某些条件下自动重新订阅失败的 Observable。例如,retry() 运算符将自动尝试重新订阅指定的次数。

3.9 Http Observables

HttpClient 上的每个请求方法都会构造并返回所请求响应类型的 Observable。使用 HttpClient 时,了解这些 Observable 的工作原理非常重要。
HttpClient 生成 RxJS 所谓的 “冷” Observable,这意味着在订阅 Observable之前不会发生任何实际请求。只有这样,请求才真正发送到服务器。多次订阅同一个 Observable会触发多个后端请求。每个订阅都是独立的。
一旦响应返回,来自 HttpClientObservable通常会自动完成(尽管拦截器会影响这一点)。
由于自动完成,如果不清理 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-TOKENcookie 中设置一个令牌。
在后续请求中,服务器可以验证 cookie 是否与 X-XSRF-TOKEN HTTP 标头匹配,因此确保只有在您的域上运行的代码才能发送请求。
令牌对于每个用户必须是唯一的,并且必须可由服务器验证;这可以防止客户端创建自己的令牌。

HttpClient 仅支持 XSRF 保护方案的客户端部分

您的后端服务必须配置为为您的页面设置 cookie,并验证标头是否存在于所有符合条件的请求中。如果不这样做,HttpClient 的 XSRF 保护就会失效。

六、全局配置

您可以使用 setupHttpClient 函数进行全局配置:

setupHttpClient(
  withFetch(),
  withXsrfProtection(),
);

七、基本用法

待续

八、拦截请求和响应

请移步:ngify 拦截请求和响应

九、测试请求

参考 angular.dev/guide/http/…

十、支持

对 @ngify/http 感兴趣?为该项目点星⭐!@ngify/http


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/952523.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

论文笔记(六十一)Implicit Behavioral Cloning

Implicit Behavioral Cloning 文章概括摘要1 引言2 背景&#xff1a;隐式模型的训练与推理3 隐式模型与显式模型的有趣属性4 policy学习成果5 理论见解&#xff1a;隐式模型的通用逼近性6 相关工作7 结论 文章概括 引用&#xff1a; inproceedings{florence2022implicit,titl…

CES 2025|美格智能高算力AI模组助力“通天晓”人形机器人震撼发布

当地时间1月7日&#xff0c;2025年国际消费电子展&#xff08;CES 2025&#xff09;在美国拉斯维加斯正式开幕。美格智能合作伙伴阿加犀联合高通在展会上面向全球重磅发布人形机器人原型机——通天晓&#xff08;Ultra Magnus&#xff09;。该人形机器人内置美格智能基于高通QC…

【安卓开发】自定义应用图标

要在 Android Studio 中设置应用的图标并自定义大小&#xff0c;可以使用 Android Studio 提供的图标生成工具。以下是具体步骤&#xff1a; 1、打开图标生成工具&#xff1a; 在 Android Studio 中&#xff0c;右键点击 res 文件夹&#xff0c;选择 New -> Image Asset。 …

django基于Python的电影推荐系统

Django 基于 Python 的电影推荐系统 一、系统概述 Django 基于 Python 的电影推荐系统是一款利用 Django 框架开发的智能化应用程序&#xff0c;旨在为电影爱好者提供个性化的电影推荐服务。该系统通过收集和分析用户的观影历史、评分数据、电影的属性信息&#xff08;如类型…

C++笔记之数据单位与C语言变量类型和范围

C++笔记之数据单位与C语言变量类型和范围 code review! 文章目录 C++笔记之数据单位与C语言变量类型和范围一、数据单位1. 数据单位表:按单位的递增顺序排列2. 关于换算关系的说明3. 一般用法及注意事项4. 扩展内容5. 理解和使用建议二、C 语言变量类型和范围基本数据类型标准…

从零开始开发纯血鸿蒙应用之多签名证书管理

从零开始开发纯血鸿蒙应用 一、前言二、鸿蒙应用配置签名证书的方式1、自动获取签名证书2、手动配置签名证书 三、多签名证书配置和使用四、多证书使用 一、前言 由于手机操作系统&#xff0c;比电脑操作系统脆弱很多&#xff0c;同时&#xff0c;由于手机的便携性&#xff0c…

OCR文字识别—基于PP-OCR模型实现ONNX C++推理部署

概述 PaddleOCR 是一款基于 PaddlePaddle 深度学习平台的开源 OCR 工具。PP-OCR是PaddleOCR自研的实用的超轻量OCR系统。它是一个两阶段的OCR系统&#xff0c;其中文本检测算法选用DB&#xff0c;文本识别算法选用CRNN&#xff0c;并在检测和识别模块之间添加文本方向分类器&a…

webpack03

什么是source-map 将代码编译压缩之后&#xff0c;&#xff0c;可以通过source-map映射会原来的代码&#xff0c;&#xff0c;&#xff0c;在调试的时候可以准确找到原代码报错位置&#xff0c;&#xff0c;&#xff0c;进行修改 source-map有很多值&#xff1a; eval &#…

H266/VVC 帧内预测中 ISP 技术

帧内子划分 ISP ISP 技术是在 JVET-2002-v3 提案中详细介绍其原理&#xff0c;在 VTM8 中完整展示算法。ISP是线基内预测&#xff08;LIP&#xff09;模式的更新版本&#xff0c;它改善了原始方法在编码增益和复杂度之间的权衡&#xff0c;ISP 算法的核心原理就是利用较近的像…

day05_Spark SQL

文章目录 day05_Spark SQL课程笔记一、今日课程内容二、Spark SQL 基本介绍&#xff08;了解&#xff09;1、什么是Spark SQL**为什么 Spark SQL 是“SQL与大数据之间的桥梁”&#xff1f;****实际意义**为什么要学习Spark SQL呢?**为什么 Spark SQL 像“瑞士军刀”&#xff1…

Win11+WLS Ubuntu 鸿蒙开发环境搭建(二)

参考文章 penHarmony南向开发笔记&#xff08;一&#xff09;开发环境搭建 OpenHarmony&#xff08;鸿蒙南向开发&#xff09;——标准系统移植指南&#xff08;一&#xff09; OpenHarmony&#xff08;鸿蒙南向开发&#xff09;——小型系统芯片移植指南&#xff08;二&…

【杂谈】-50+个生成式人工智能面试问题(四)

7、生成式AI面试问题与微调相关 Q23. LLMs中的微调是什么&#xff1f; 答案&#xff1a;虽然预训练语言模型非常强大&#xff0c;但它们并不是任何特定任务的专家。它们可能对语言有惊人的理解能力&#xff0c;但仍需要一些LLMs微调过程&#xff0c;开发者通过这个过程提升它…

【深度学习】数据预处理

为了能用深度学习来解决现实世界的问题&#xff0c;我们经常从预处理原始数据开始&#xff0c; 而不是从那些准备好的张量格式数据开始。 在Python中常用的数据分析工具中&#xff0c;我们通常使用pandas软件包。 像庞大的Python生态系统中的许多其他扩展包一样&#xff0c;pan…

赛灵思(Xilinx)公司Artix-7系列FPGA

苦难从不值得歌颂&#xff0c;在苦难中萃取的坚韧才值得珍视&#xff1b; 痛苦同样不必美化&#xff0c;从痛苦中开掘出希望才是壮举。 没有人是绝对意义的主角&#xff0c; 但每个人又都是自己生活剧本里的英雄。滑雪&#xff0c;是姿态优雅的“贴地飞行”&#xff0c;也有着成…

城市生命线安全综合监管平台

【落地产品&#xff0c;有需要可留言联系&#xff0c;支持项目合作或源码合作】 一、建设背景 以关于城市安全的重要论述为建设纲要&#xff0c;聚焦城市安全重点领域&#xff0c;围绕燃气爆炸、城市内涝、地下管线交互风险、第三方施工破坏、供水爆管、桥梁坍塌、道路塌陷七…

请求方式(基于注解实现)

1.编写web.xml文件配置启动信息 <!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app><display-name>Archetype Created Web Application</di…

WMS仓库管理系统,Vue前端开发,Java后端技术源码(源码学习)

一、项目背景和建设目标 随着企业业务的不断扩展&#xff0c;仓库管理成为影响生产效率、成本控制及客户满意度的重要环节。为了提升仓库作业的透明度、准确性和效率&#xff0c;本方案旨在构建一套全面、高效、易用的仓库管理系统&#xff08;WMS&#xff09;。该系统将涵盖库…

Pathview包:整合表达谱数据可视化KEGG通路

Pathview是一个用于整合表达谱数据并用于可视化KEGG通路的一个R包&#xff0c;其会先下载KEGG官网上的通路图&#xff0c;然后整合输入数据对通路图进行再次渲染&#xff0c;从而对KEGG通路图进行一定程度上的个性化处理&#xff0c;并且丰富其信息展示。&#xff08;KEGG在线数…

数据结构:DisjointSet

Disjoint Sets意思是一系列没有重复元素的集合。一种常见的实现叫做&#xff0c;Disjoint-set Forest可以以接近常数的时间复杂度查询元素所属集合&#xff0c;用来确定两个元素是否同属一个集合等&#xff0c;是效率最高的常见数据结构之一。 Wiki链接&#xff1a;https://en…

更好的世界:用定制托管对象上下文(NSManagedObjectContext)防止产生“空白”托管对象(下)

概述 用 SwiftUI CoreData 这对“双剑合璧”的强力开发组合&#xff0c;我们可以事倍功半、非常 easy 的开发出界面元素丰富且背后拥有持久数据库支持的 App。 不过&#xff0c;在某些情况下它们被误用或错用也可能带来一些“藏形匿影”的顽疾。 在本篇博文中&#xff0c;您…