MST

星途 面试题库

面试题:Angular HttpClient模块下请求体构建与拦截器结合的应用

在一个Angular应用中,你需要在每次发送POST请求时,对请求体进行特定格式的转换(例如将所有字符串类型的字段首字母大写)。请实现一个拦截器来处理这个需求,同时说明如何在构建请求体时确保与拦截器的协作正常,以及如何处理拦截器中可能出现的异常情况。
21.6万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试
  1. 实现拦截器
    • 首先,在Angular中创建一个拦截器类,该类需要实现HttpInterceptor接口。假设我们的项目使用TypeScript,代码如下:
    import { Injectable } from '@angular/core';
    import {
      HttpEvent,
      HttpHandler,
      HttpInterceptor,
      HttpRequest
    } from '@angular/common/http';
    import { Observable } from 'rxjs';
    
    @Injectable()
    export class RequestBodyInterceptor implements HttpInterceptor {
      intercept(
        request: HttpRequest<any>,
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
        if (request.method === 'POST') {
          const transformedBody = this.transformRequestBody(request.body);
          request = request.clone({
            body: transformedBody
          });
        }
        return next.handle(request);
      }
    
      private transformRequestBody(body: any): any {
        if (!body) {
          return body;
        }
        if (typeof body ==='string') {
          return body.charAt(0).toUpperCase() + body.slice(1);
        } else if (Array.isArray(body)) {
          return body.map((item) => this.transformRequestBody(item));
        } else if (typeof body === 'object') {
          const newBody: any = {};
          for (const key in body) {
            if (Object.prototype.hasOwnProperty.call(body, key)) {
              newBody[key] = this.transformRequestBody(body[key]);
            }
          }
          return newBody;
        }
        return body;
      }
    }
    
  2. 在构建请求体时确保与拦截器的协作正常
    • 构建请求体时,无需额外操作来确保与拦截器协作。只要使用HttpClient发送POST请求,拦截器会自动生效。例如:
    import { Component } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    
    @Component({
      selector: 'app - my - component',
      templateUrl: './my - component.html'
    })
    export class MyComponent {
      constructor(private http: HttpClient) {}
    
      sendPostRequest() {
        const requestBody = {
          name: 'john',
          message: 'hello world'
        };
        this.http.post('/api/some - endpoint', requestBody).subscribe((response) => {
          console.log(response);
        });
      }
    }
    
    • 拦截器会在请求发送前自动捕获POST请求,并对请求体进行转换。
  3. 处理拦截器中可能出现的异常情况
    • 在拦截器中,异常处理可以通过在next.handle(request)catchError操作符来实现。例如:
    import { Injectable } from '@angular/core';
    import {
      HttpEvent,
      HttpHandler,
      HttpInterceptor,
      HttpRequest
    } from '@angular/common/http';
    import { Observable, catchError } from 'rxjs';
    
    @Injectable()
    export class RequestBodyInterceptor implements HttpInterceptor {
      intercept(
        request: HttpRequest<any>,
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
        if (request.method === 'POST') {
          const transformedBody = this.transformRequestBody(request.body);
          request = request.clone({
            body: transformedBody
          });
        }
        return next.handle(request).pipe(
          catchError((error) => {
            // 在这里处理异常,例如记录日志
            console.error('Request error in interceptor:', error);
            throw error;
          })
        );
      }
    
      private transformRequestBody(body: any): any {
        if (!body) {
          return body;
        }
        if (typeof body ==='string') {
          return body.charAt(0).toUpperCase() + body.slice(1);
        } else if (Array.isArray(body)) {
          return body.map((item) => this.transformRequestBody(item));
        } else if (typeof body === 'object') {
          const newBody: any = {};
          for (const key in body) {
            if (Object.prototype.hasOwnProperty.call(body, key)) {
              newBody[key] = this.transformRequestBody(body[key]);
            }
          }
          return newBody;
        }
        return body;
      }
    }
    
    • 上述代码在catchError中简单地记录了错误日志,并重新抛出错误,以便上层的订阅者可以处理该错误。在实际应用中,可以根据需求进行更复杂的异常处理,如显示用户友好的错误提示等。

还需要在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 { RequestBodyInterceptor } from './request - body - interceptor';

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