Angular SPA 应用中如何通过拦截器实现统一处理 HTTP 请求错误

在 Angular 单页应用(SPA)中,我们经常需要调用后端 API 来获取数据。但是,在实际开发中,由于网络、服务器等各种原因,我们的 HTTP 请求可能会出现错误,例如请求超时、404 等。为了更好地处理这些错误,我们可以通过拦截器来实现统一处理。

什么是拦截器

拦截器是 Angular 提供的一种机制,用于在 HTTP 请求和响应中添加额外的处理逻辑。拦截器可以用来修改请求头、处理响应体等。在拦截器中,我们可以对请求进行拦截,然后做出相应的处理,例如重试、错误提示等。

如何使用拦截器

  1. 创建一个拦截器类
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      catchError((error: any) => {
        if (error.status === 401) {
          // 处理 401 错误
        } else if (error.status === 404) {
          // 处理 404 错误
        } else {
          // 处理其他错误
        }
        return throwError(error);
      })
    );
  }
}

在上面的代码中,我们创建了一个名为 ErrorInterceptor 的拦截器类,并实现了 HttpInterceptor 接口。在 intercept 方法中,我们首先调用 next.handle(request) 来执行请求,然后使用 catchError 操作符来捕获错误。在捕获到错误后,我们可以根据错误的状态码来进行相应的处理。

  1. 注册拦截器

我们可以通过在 app.module.ts 文件中的 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 { ErrorInterceptor } from './error.interceptor';

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

在上面的代码中,我们通过 HTTP_INTERCEPTORS 标记来指定我们要注册的拦截器,并将其添加到 providers 数组中。需要注意的是,我们需要将 multi 属性设置为 true,以便支持多个拦截器。

示例代码

下面是一个完整的示例代码,它演示了如何使用拦截器来处理 HTTP 请求错误。

import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(
      catchError((error: any) => {
        if (error.status === 401) {
          // 处理 401 错误
        } else if (error.status === 404) {
          // 处理 404 错误
        } else {
          // 处理其他错误
        }
        return throwError(error);
      })
    );
  }
}

@Injectable()
export class ApiService {
  constructor(private http: HttpClient) {}

  getData(): Observable<any> {
    return this.http.get('https://example.com/api/data');
  }
}

@Component({
  selector: 'app-root',
  template: `
    <button (click)="getData()">获取数据</button>
    <div>{{ data }}</div>
  `,
})
export class AppComponent {
  data: any;

  constructor(private apiService: ApiService) {}

  getData() {
    this.apiService.getData().subscribe(
      (response) => {
        this.data = response;
      },
      (error) => {
        console.error(error);
      }
    );
  }
}

在上面的代码中,我们创建了一个名为 ApiService 的服务,它使用 HttpClient 来获取数据。我们还创建了一个名为 AppComponent 的组件,它包含一个按钮和一个用于显示数据的 DIV 元素。当用户点击按钮时,我们会调用 apiService.getData() 方法来获取数据。如果请求出现错误,我们会在控制台中打印错误信息。

总结

通过拦截器,我们可以在 Angular SPA 应用中实现统一处理 HTTP 请求错误的逻辑。拦截器可以用来捕获错误、重试、错误提示等。在实际开发中,我们可以根据自己的需求来自定义拦截器,以提高代码的可读性和可维护性。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/658e1d38eb4cecbf2d3eed8d


纠错
反馈