MST

星途 面试题库

面试题:Angular HTTP请求方法与参数传递的优化及异常处理

在一个高并发的Angular应用中,大量的HTTP请求会带来性能问题。请从请求方法的选择、参数传递的优化以及HTTP拦截器等方面阐述如何提升HTTP请求的效率和稳定性。例如,如何合理使用缓存机制减少不必要的请求,如何通过HTTP拦截器统一处理请求参数和响应数据,以及在请求过程中遇到网络异常、服务器错误等情况时,如何进行优雅的异常处理和用户提示。要求给出具体的代码示例和架构设计思路。
43.8万 热度难度
前端开发Angular

知识考点

AI 面试

面试题答案

一键面试

请求方法选择

  1. GET:用于获取数据,幂等且可缓存。适用于查询操作,例如获取用户信息。
    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    
    @Injectable({
      providedIn: 'root'
    })
    export class UserService {
      constructor(private http: HttpClient) {}
    
      getUser(id: number) {
        return this.http.get(`api/users/${id}`);
      }
    }
    
  2. POST:用于创建新资源,非幂等且不可缓存。适用于提交表单等操作,如注册新用户。
    @Injectable({
      providedIn: 'root'
    })
    export class AuthService {
      constructor(private http: HttpClient) {}
    
      registerUser(userData: any) {
        return this.http.post('api/register', userData);
      }
    }
    

参数传递优化

  1. URL参数:简单参数可放在URL中,适用于GET请求。
    @Injectable({
      providedIn: 'root'
    })
    export class ProductService {
      constructor(private http: HttpClient) {}
    
      getProductsByCategory(category: string) {
        return this.http.get(`api/products?category=${category}`);
      }
    }
    
  2. 请求体:复杂数据结构使用请求体,适用于POST、PUT等请求。
    @Injectable({
      providedIn: 'root'
    })
    export class OrderService {
      constructor(private http: HttpClient) {}
    
      placeOrder(orderData: any) {
        return this.http.post('api/orders', orderData);
      }
    }
    

缓存机制

  1. 客户端缓存:使用RxJS的shareReplay操作符实现简单缓存。
    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable, shareReplay } from 'rxjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class DataService {
      private cachedData$: Observable<any>;
    
      constructor(private http: HttpClient) {}
    
      getData() {
        if (!this.cachedData$) {
          this.cachedData$ = this.http.get('api/data').pipe(
            shareReplay(1)
          );
        }
        return this.cachedData$;
      }
    }
    

HTTP拦截器

  1. 统一处理请求参数:添加通用请求头。
    import { Injectable } from '@angular/core';
    import {
      HttpEvent,
      HttpHandler,
      HttpInterceptor,
      HttpRequest
    } from '@angular/common/http';
    import { Observable } from 'rxjs';
    
    @Injectable()
    export class AuthInterceptor implements HttpInterceptor {
      intercept(
        request: HttpRequest<any>,
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
        const token = localStorage.getItem('token');
        if (token) {
          request = request.clone({
            setHeaders: {
              Authorization: `Bearer ${token}`
            }
          });
        }
        return next.handle(request);
      }
    }
    
  2. 统一处理响应数据:处理错误响应。
    import { Injectable } from '@angular/core';
    import {
      HttpEvent,
      HttpHandler,
      HttpInterceptor,
      HttpRequest,
      HttpResponse
    } from '@angular/common/http';
    import { Observable, catchError, tap } from 'rxjs';
    import { ToastrService } from 'ngx-toastr';
    
    @Injectable()
    export class ErrorInterceptor implements HttpInterceptor {
      constructor(private toastr: ToastrService) {}
    
      intercept(
        request: HttpRequest<any>,
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
          tap((event: HttpEvent<any>) => {
            if (event instanceof HttpResponse) {
              // 可在此处理成功响应
            }
          }),
          catchError((error) => {
            if (error.status === 401) {
              this.toastr.error('请重新登录', '未授权');
            } else if (error.status === 500) {
              this.toastr.error('服务器错误', '系统故障');
            }
            throw error;
          })
        );
      }
    }
    

架构设计思路

  1. 模块划分:将HTTP请求相关逻辑封装到服务中,如UserServiceProductService等,提高代码可维护性。
  2. 拦截器配置:在app.module.ts中配置拦截器,确保所有HTTP请求都经过处理。
    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 { AuthInterceptor } from './auth.interceptor';
    import { ErrorInterceptor } from './error.interceptor';
    
    @NgModule({
      declarations: [AppComponent],
      imports: [BrowserModule, HttpClientModule],
      providers: [
        {
          provide: HTTP_INTERCEPTORS,
          useClass: AuthInterceptor,
          multi: true
        },
        {
          provide: HTTP_INTERCEPTORS,
          useClass: ErrorInterceptor,
          multi: true
        }
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule {}
    
  3. 缓存管理:对于不同类型的数据,根据其更新频率和重要性,选择合适的缓存策略,如客户端缓存、服务器端缓存等。
  4. 异常处理:通过拦截器统一处理异常,向用户提供友好的提示信息,同时记录错误日志以便排查问题。