欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > ngify 拦截请求和响应

ngify 拦截请求和响应

2025/3/24 14:14:01 来源:https://blog.csdn.net/mss359681091/article/details/145082578  浏览:    关键词:ngify 拦截请求和响应

文章目录

  • 前言
  • 一、什么是ngify?
  • 二、拦截请求和响应
    • 2.1 拦截器
    • 2.2 定义拦截器
    • 2.3 配置拦截器
    • 2.4 拦截响应事件
    • 2.5 修改请求
    • 2.6 请求和响应元数据
    • 2.7 定义上下文标记
    • 2.8 在拦截器中读取令牌
    • 2.9 发出请求时设置上下文令牌
    • 2.10 请求上下文是可变的
    • 2.11 构造响应
    • 2.12 基于 class 的拦截器
  • 三、ngify 介绍


前言

这篇文章主要介绍了 @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 相同的严格单元测试,确保了其代码质量和可靠性,在各种场景下保持足够的稳定性。

详情请移步:what?ngify 比 axios 更好用,更强大?

🎯本篇只介绍 拦截请求和响应。

二、拦截请求和响应

HttpClient 支持一种称为拦截器的中间件形式。

拦截器是中间件,允许从单个请求中抽象出有关重试、缓存、日志记录和身份验证的常见模式。

axios 需要分别配置请求拦截器和响应拦截器不同,@ngify/http 的单个拦截器就能同时处理请求和响应,这使得拦截逻辑更加紧凑,方便开发者管理。

HttpClient 支持两种拦截器:函数式拦截器和基于 class 的拦截器。我们的建议是使用函数式拦截器,因为它们具有更可预测的行为,尤其是在复杂的设置中。本指南中的示例使用函数式拦截器,并且我们在最后的相应部分中介绍了基于 class 的拦截器。

2.1 拦截器

拦截器通常是可以为每个请求运行的函数,并且具有影响请求和响应的内容和整体流程的广泛功能。

您可以安装多个拦截器,它们形成拦截器链,其中每个拦截器处理请求或响应,然后将其转发到链中的下一个拦截器。

您可以使用拦截器来实现各种常见模式,例如:

  • 将身份验证标头添加到发送到特定 API 的传出请求。
  • 使用指数退避重试失败的请求。
  • 将响应缓存一段时间,或者直到因突变而失效。
  • 自定义响应的解析。
  • 测量服务器响应时间并记录它们。
  • 在网络操作正在进行时驱动 UI 元素,例如加载旋转器。
  • 收集并批量处理特定时间范围内发出的请求。
  • 在可配置的截止日期或超时后自动失败请求。
  • 定期轮询服务器并刷新结果。

2.2 定义拦截器

拦截器的基本形式是接收传出 HttpRequest 的函数和代表拦截器链中下一个处理步骤的 next 函数。

例如,此 loggingInterceptor 将在转发请求之前将传出请求 URL 记录到 console.log

export function loggingInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> {console.log(req.url);return next(req);
}

为了让这个拦截器真正拦截请求,您必须配置 HttpClient 来使用它。

2.3 配置拦截器

您可以使用 withInterceptors 函数配置 HttpClient 要使用的拦截器集合:

const http = new HttpClient(withInterceptors([loggingInterceptor, cachingInterceptor])
);

您配置的拦截器按照您列出的顺序链接在一起。在上面的示例中,loggingInterceptor 将处理请求,然后将其转发到 cachingInterceptor

2.4 拦截响应事件

拦截器可以转换 next 返回的 HttpEventObservable 流,以便访问或操作响应。由于此流包含所有响应事件,因此可能需要检查每个事件的 .type 以便识别最终响应对象。

export function loggingInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> {return next(req).pipe(tap(event => {if (event.type === HttpEventType.Response) {console.log(req.url, 'returned a response with status', event.status);}}));
}

TIP:拦截器自然地将响应与其传出请求相关联,因为它们在捕获请求对象的闭包中转换响应流。

2.5 修改请求

HttpRequestHttpResponse 实例的大多数方面都是不可变的,拦截器无法直接修改它们。相反,拦截器通过使用 .clone() 操作克隆这些对象并指定应在新实例中改变哪些属性来应用变更。这可能涉及对值本身执行不可变的更新(如 HttpHeadersHttpParams)。

例如,要向请求添加标头:

const reqWithHeader = req.clone({headers: req.headers.set('X-New-Header', 'new header value'),
});

如果多次将同一个 HttpRequest 提交到拦截器链,这种不变性允许大多数拦截器具有幂等性。发生这种情况的原因有多种,包括请求失败后重试时。

🎯注意:请求或响应的正文未受到深度变更的保护。如果拦截器必须改变主体,请注意处理同一请求的多次运行。

2.6 请求和响应元数据

通常,在不发送到后端但专门用于拦截器的请求中包含信息很有用。 HttpRequest 有一个 .context 对象,它将此类元数据存储为 HttpContext 的实例。该对象充当类型映射,其键类型为 HttpContextToken
为了说明该系统的工作原理,让我们使用元数据来控制是否为给定的请求启用缓存拦截器。

2.7 定义上下文标记

要存储缓存拦截器是否应在该请求的 .context 映射中缓存特定请求,请定义一个新的 HttpContextToken 来充当键:

export const CACHING_ENABLED = new HttpContextToken<boolean>(() => true);

提供的函数为尚未显式设置值的请求创建令牌的默认值。使用函数可确保如果令牌的值是对象或数组,则每个请求都会获得自己的实例。

2.8 在拦截器中读取令牌

然后,拦截器可以读取令牌并根据其值选择是否应用缓存逻辑:

export function cachingInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> {if (req.context.get(CACHING_ENABLED)) {// apply caching logicreturn ...;} else {// caching has been disabled for this requestreturn next(req);}
}

2.9 发出请求时设置上下文令牌

通过 HttpClient API 发出请求时,您可以为 HttpContextToken 提供值:

const data$ = http.get('/sensitive/data', {context: new HttpContext().set(CACHING_ENABLED, false),
});

拦截器可以从请求的 HttpContext 中读取这些值。

2.10 请求上下文是可变的

HttpRequest 的其他属性不同,关联的 HttpContext 是可变的。如果拦截器更改了稍后重试的请求的上下文,则同一拦截器在再次运行时将观察到上下文变化。如果需要,这对于在多次重试之间传递状态很有用。

2.11 构造响应

大多数拦截器将在转换请求或响应时简单地调用下 next 函数,但这并不是严格的要求。本节讨论拦截器可以合并更高级行为的几种方法。

拦截器不需要调用 next。它们可能会选择通过其他一些机制来构造响应,例如从缓存中或通过替代机制发送请求。

可以使用 HttpResponse 构造函数构建响应:

const resp = new HttpResponse({body: 'response body',
});

2.12 基于 class 的拦截器

HttpClient 还支持基于 class 的拦截器,基于 class 的拦截器与函数式拦截器的功能相同,但配置方法不同。

基于 class 的拦截器是一个实现 HttpInterceptor 接口的类:

export class LoggingInterceptor implements HttpInterceptor {intercept(req: HttpRequest<any>, handler: HttpHandler): Observable<HttpEvent<any>> {console.log('Request URL: ' + req.url);return handler.handle(req);}
}

基于 class 的拦截器通过 withLegacyInterceptors 函数进行配置:

const http = new HttpClient(withLegacyInterceptors([new LoggingInterceptor()]),withInterceptors([cachingInterceptor])
);

三、ngify 介绍

详情请移步:what?ngify 比 axios 更好用,更强大?


在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词