MST

星途 面试题库

面试题:Angular HTTP请求拦截器的复杂应用场景及优化

在一个大型企业级Angular项目中,存在多种类型的HTTP请求,且不同业务模块对请求和响应的处理有不同需求。请阐述如何设计一个灵活可扩展的HTTP请求拦截器架构,使其能满足各模块差异化的处理需求,同时要考虑性能优化和代码的可维护性,给出详细设计思路及关键代码结构。
38.1万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 模块化设计:将不同业务模块的请求和响应处理逻辑拆分为独立的模块,每个模块负责自身业务相关的处理。这样可以提高代码的可维护性,使得每个业务模块的逻辑清晰,互不干扰。
  2. 链式调用:采用链式调用的方式组织拦截器,每个拦截器处理完请求或响应后,将控制权传递给下一个拦截器。这种方式使得整个请求和响应处理流程具有灵活性,可以根据业务需求轻松添加、删除或调整拦截器的顺序。
  3. 依赖注入:使用Angular的依赖注入机制,将拦截器注册到Angular的注入器中。这样可以方便地在不同组件或服务中使用拦截器,同时也便于管理拦截器的生命周期。
  4. 配置驱动:通过配置文件或配置服务,定义不同业务模块需要使用的拦截器。这样可以在不修改代码的情况下,灵活调整各业务模块的请求和响应处理逻辑,提高系统的可扩展性。
  5. 性能优化
    • 缓存机制:对于一些不经常变化的请求,可以在拦截器中实现缓存机制,避免重复请求,提高响应速度。
    • 并行处理:对于一些相互独立的请求,可以在拦截器中实现并行处理,减少整体请求时间。

关键代码结构

  1. 创建基础拦截器类
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class BaseInterceptor implements HttpInterceptor {
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // 通用请求处理逻辑,如添加公共headers
        const modifiedRequest = request.clone({
            setHeaders: {
                'Content-Type': 'application/json'
            }
        });
        return next.handle(modifiedRequest);
    }
}
  1. 创建业务模块特定拦截器
import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class BusinessModule1Interceptor implements HttpInterceptor {
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // 业务模块1的请求处理逻辑,如添加特定headers
        const modifiedRequest = request.clone({
            setHeaders: {
                'Business-Module-1-Header': 'value'
            }
        });
        return next.handle(modifiedRequest);
    }
}
  1. 注册拦截器: 在app.module.ts中注册拦截器:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform - browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { BaseInterceptor } from './base.interceptor';
import { BusinessModule1Interceptor } from './business - module1.interceptor';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, HttpClientModule],
    providers: [
        { provide: HTTP_INTERCEPTORS, useClass: BaseInterceptor, multi: true },
        { provide: HTTP_INTERCEPTORS, useClass: BusinessModule1Interceptor, multi: true }
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}
  1. 配置驱动的拦截器使用: 可以创建一个配置服务来管理不同业务模块的拦截器配置:
import { Injectable } from '@angular/core';

@Injectable()
export class InterceptorConfigService {
    private businessModule1Interceptors = [BaseInterceptor, BusinessModule1Interceptor];

    getInterceptorsForBusinessModule1() {
        return this.businessModule1Interceptors;
    }
}

然后在模块的providers中根据配置动态注册拦截器:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform - browser';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { BaseInterceptor } from './base.interceptor';
import { BusinessModule1Interceptor } from './business - module1.interceptor';
import { InterceptorConfigService } from './interceptor - config.service';

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule, HttpClientModule],
    providers: [
        InterceptorConfigService,
        ...(new InterceptorConfigService().getInterceptorsForBusinessModule1().map(interceptor => ({
            provide: HTTP_INTERCEPTORS,
            useClass: interceptor,
            multi: true
        })))
    ],
    bootstrap: [AppComponent]
})
export class AppModule {}