MST

星途 面试题库

面试题:Angular中HTTP请求拦截器在动态数据加载场景下的复杂应用

在一个Angular应用中,有多个组件需要通过HTTP请求动态加载数据。现在要求实现一个HTTP请求拦截器,用于在每次请求前添加特定的请求头(如根据用户登录状态添加 'Authorization' 头),并且在响应返回时,统一处理不同类型的错误(如401未授权、500服务器错误)。同时,拦截器需要能够处理不同类型的HTTP请求(GET、POST等),并且在处理错误时要能够根据不同组件的需求进行差异化处理(例如某些组件需要弹出提示框,某些组件需要跳转到特定页面)。请详细说明拦截器的实现思路以及关键代码结构。
48.5万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 创建HTTP拦截器:使用Angular的HttpInterceptor接口来创建一个拦截器类。
  2. 添加请求头:在intercept方法中,获取当前请求,克隆请求并添加特定的请求头(如Authorization)。
  3. 处理响应错误:使用catchError操作符来捕获响应中的错误,根据不同的错误状态码(如401、500)进行处理。
  4. 差异化处理:通过注入一个服务,在不同组件中配置不同的错误处理逻辑,拦截器调用该服务的方法来实现差异化处理。

关键代码结构

  1. 创建拦截器类
import { Injectable } from '@angular/core';
import {
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest,
} from '@angular/common/http';
import { Observable, catchError } from 'rxjs';
import { ErrorHandlingService } from './error - handling.service';

@Injectable()
export class CustomHttpInterceptor implements HttpInterceptor {
  constructor(private errorHandlingService: ErrorHandlingService) {}

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    // 添加请求头
    const authToken = localStorage.getItem('token');// 假设从localStorage获取token
    const newRequest = request.clone({
      headers: request.headers.set('Authorization', `Bearer ${authToken}`),
    });

    return next.handle(newRequest).pipe(
      catchError((error) => {
        // 处理不同类型错误
        if (error.status === 401) {
          return this.errorHandlingService.handle401Error(error);
        } else if (error.status === 500) {
          return this.errorHandlingService.handle500Error(error);
        }
        throw error;
      })
    );
  }
}
  1. 错误处理服务
import { Injectable } from '@angular/core';
import {
  HttpErrorResponse,
  HttpEvent,
  HttpHandler,
  HttpRequest,
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';

@Injectable()
export class ErrorHandlingService {
  handle401Error(error: HttpErrorResponse): Observable<HttpEvent<any>> {
    // 例如,某些组件弹出提示框
    // 这里假设通过一个共享服务来通知组件弹出提示框
    // 或者直接在某些页面进行导航
    return throwError(() => error);
  }

  handle500Error(error: HttpErrorResponse): Observable<HttpEvent<any>> {
    // 例如,某些组件跳转到特定页面
    // 同样可以通过共享服务或直接导航
    return throwError(() => error);
  }
}
  1. 在模块中注册拦截器
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 { CustomHttpInterceptor } from './custom - http.interceptor';
import { ErrorHandlingService } from './error - handling.service';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, HttpClientModule],
  providers: [
    ErrorHandlingService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: CustomHttpInterceptor,
      multi: true,
    },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}