Angular 如何通过 HTTP Interceptor 实现 HTTP 请求的超时监控

简介: 当开发人员在 Dynatrace 中查看这些请求时,将无法再看到超时后正在进行的 API 调用。

当开发人员在 Dynatrace 中查看这些请求时,将无法再看到超时后正在进行的 API 调用。 该过程在后台进行渲染,但 Dynatrace 看到返回给客户端的响应并停止记录,在这种情况下,如果能了解它正在做的事情需要这么长时间,对分析问题会更有帮助。


我们可以引入一个 Angular HTTP_INTERCEPTOR 来超时等待已久的网络请求,从而确保在服务器端引导的应用程序具有更短的生命周期。 换句话说:所以 SSR 渲染不会因为等待来自网络的缓慢 API响应而 挂起。 但是,这可能需要在应用程序代码甚至 SSR 代码中添加额外的逻辑,以便在 SSR 响应中不会返回此类格式错误的渲染(基于不完整的数据)。在这种情况下,最好回退到没有缓存标头的 CSR 应用程序,而不是允许格式错误的渲染 html 作为响应发送(并且可能由 CDN 缓存)。

一个例子。

在 app.module.ts 里的代码:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { RequestTimeoutHttpInterceptor, DEFAULT_TIMEOUT } from './interceptors';
import { AppComponent } from './app.component';
@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule,
  ],
  declarations: [
    AppComponent,
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: RequestTimeoutHttpInterceptor, multi: true },
    { provide: DEFAULT_TIMEOUT, useValue: 5000 },
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

interceptor 的实现:

import { Injectable, InjectionToken, Inject } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { empty, TimeoutError } from 'rxjs';
import { timeout, catchError } from 'rxjs/operators';
export const DEFAULT_TIMEOUT = new InjectionToken<number>('defaultTimeout');
@Injectable({
  providedIn: 'root'
})
export class RequestTimeoutHttpInterceptor implements HttpInterceptor {
  constructor(
    @Inject(DEFAULT_TIMEOUT) protected defaultTimeout: number,
  ) { }
  intercept(req: HttpRequest<any>, next: HttpHandler) {
    const modified = req.clone({
      setHeaders: { 'X-Request-Timeout': `${this.defaultTimeout}` }
    });
    return next.handle(modified).pipe(
      timeout(this.defaultTimeout),
      catchError(err => {
        if (err instanceof TimeoutError)
          console.error('Timeout has occurred', req.url);
        return empty();
      })
    );
  }
}

这里使用了 rxjs 的 timeout 操作符。如果在指定的时间间隔之内没有 emit 值,则会抛出 error.

看下面这个例子:

// RxJS v6+
import { of } from 'rxjs';
import { concatMap, timeout, catchError, delay } from 'rxjs/operators';
// simulate request
function makeRequest(timeToDelay) {
  return of('Request Complete!').pipe(delay(timeToDelay));
}
of(4000, 3000, 2000)
  .pipe(
    concatMap(duration =>
      makeRequest(duration).pipe(
        timeout(2500),
        catchError(error => of(`Request timed out after: ${duration}`))
      )
    )
  )
  /*
   *  "Request timed out after: 4000"
   *  "Request timed out after: 3000"
   *  "Request Complete!"
   */
  .subscribe(val => console.log(val));

image.png

在这段代码里,我们首先使用 delay 操作符,在 makeRequest 函数里指定了一个时间间隔,来模拟函数调用的延迟。


然后将 makeRequest 返回的 Observable,添加了一个 timeout(2500) 的操作符,意思是 2.5 秒之内,如果该 Observable 没有发出值,即进入 CatchError 的处理逻辑内。


数据源头有三个值,4000,3000 和 2000,其中只有最后一个值小于 2500,因此能在超时时间间隔之内完成函数调用。其他两个值都会导致超时,从而进入 catchError 的数据打印。



目录
相关文章
|
6小时前
|
应用服务中间件 nginx
百度搜索:蓝易云【HTTP请求是如何关联Nginx server{}块的?】
总结来说,Nginx中的 `server{}`块用于关联HTTP请求和虚拟主机,通过配置不同的 `server{}`块,可以实现多个域名或IP地址的请求分发和处理。这样,Nginx可以根据不同的请求来提供不同的服务和内容。
39 0
|
6小时前
|
存储 缓存 API
HTTP 请求的响应头部字段 Cache-Control 的值为 no-store 是什么意思
HTTP 请求的响应头部字段 Cache-Control 的值为 no-store 是什么意思
80 0
|
6小时前
|
JavaScript
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)(上)
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
32 0
|
6小时前
|
JavaScript
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)(下)
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
27 0
|
6小时前
|
数据采集 缓存 前端开发
http和https请求服务器的时候在请求头部分都带什么到服务器呢?
HTTP和HTTPS请求头基本结构相似,HTTPS多了一层SSL/TLS加密。常见请求头如Accept(指定内容类型)、Authorization(身份验证)、Cookie(会话跟踪)、User-Agent(标识用户代理)等。HTTPS特有的头包括Upgrade-Insecure-Requests(升级到HTTPS)、Strict-Transport-Security(强制使用HTTPS)、Sec-Fetch-*(安全策略)和X-Content-Type-Options、X-Frame-Options等(增强安全性)。实际应用中,请求头会根据需求和安全策略变化。
24 0
|
6小时前
|
Java API Spring
使用OkHttp在Spring Boot应用中发送HTTP请求
使用OkHttp在Spring Boot应用中发送HTTP请求
106 0
|
6小时前
|
存储 缓存 安全
面试题:HTTP 协议包括哪些请求?
面试题:HTTP 协议包括哪些请求?
25 0
|
6小时前
|
移动开发 自然语言处理 网络协议
Http解析实现/服务器Get请求的实现
Http解析实现/服务器Get请求的实现
50 0
|
6小时前
|
Web App开发 网络协议 Linux
Linux C/C++ 开发(学习笔记十 ):实现http请求器(TCP客户端)
Linux C/C++ 开发(学习笔记十 ):实现http请求器(TCP客户端)
59 0
|
6小时前
|
JavaScript Java Serverless
函数计算中,这里是用的curl的方式,如何改用http的post方式请求?还有如何设置oss打包的zip的保存目录?
函数计算中,这里是用的curl的方式,如何改用http的post方式请求?还有如何设置oss打包的zip的保存目录?
161 0