告别重复编码:Angular拦截器让HTTP请求处理自动化
你还在为每个HTTP请求重复添加认证Token?还在为分散的错误处理逻辑头疼?Angular拦截器(Interceptor)将彻底解决这些问题!本文将带你掌握如何使用拦截器实现请求统一处理,包括认证头自动附加、全局错误捕获、请求/响应日志记录等核心场景,让你的代码更简洁、更易维护。
什么是Angular拦截器
Angular拦截器是一种中间件机制,用于在HTTP请求发送前和响应返回后进行统一处理。它基于HttpInterceptor接口实现,允许开发者拦截、修改和转换HTTP请求/响应,而无需在每个请求处重复编写相同逻辑。
拦截器的核心接口定义在packages/common/http/src/interceptor.ts中:
export interface HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
}
拦截器工作流程
拦截器通过链式调用处理请求,每个拦截器可以决定是否修改请求、传递给下一个拦截器或直接返回响应。以下是典型的拦截器链工作流程:
实战:创建你的第一个拦截器
步骤1:实现拦截器类
创建一个认证拦截器,自动为所有请求添加Bearer Token:
// src/app/interceptors/auth.interceptor.ts
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor() {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
// 从本地存储获取token
const token = localStorage.getItem('auth_token');
if (token) {
// 克隆请求并添加认证头
const authReq = request.clone({
headers: request.headers.set('Authorization', `Bearer ${token}`)
});
return next.handle(authReq);
}
return next.handle(request);
}
}
步骤2:注册拦截器
在应用模块中通过HTTP_INTERCEPTORS令牌注册拦截器:
// src/app/app.module.ts
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './interceptors/auth.interceptor';
@NgModule({
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true // 允许多个拦截器并存
}
]
})
export class AppModule { }
HTTP_INTERCEPTORS令牌定义在packages/common/http/src/interceptor.ts中,是一个多提供商令牌,支持同时注册多个拦截器。
高级应用场景
1. 全局错误处理
创建错误拦截器统一处理API错误:
// src/app/interceptors/error.interceptor.ts
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Router } from '@angular/router';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
return next.handle(request).pipe(
catchError((error: HttpErrorResponse) => {
switch (error.status) {
case 401:
// 未授权,重定向到登录页
this.router.navigate(['/login']);
break;
case 403:
// 禁止访问,显示提示
alert('您没有权限访问该资源');
break;
case 500:
// 服务器错误,记录日志
console.error('服务器错误:', error.message);
break;
}
return throwError(() => error);
})
);
}
}
2. 请求/响应日志记录
实现日志拦截器跟踪API调用:
// src/app/interceptors/log.interceptor.ts
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class LogInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
const startTime = Date.now();
// 记录请求信息
console.log(`请求: ${request.method} ${request.url}`);
return next.handle(request).pipe(
tap({
next: (event) => {
if (event.type === 4) { // 响应完成事件
const duration = Date.now() - startTime;
console.log(`响应: ${request.url} (${duration}ms)`);
}
},
error: (error) => {
console.error(`请求失败: ${request.url}`, error);
}
})
);
}
}
拦截器注册与执行顺序
多个拦截器的注册顺序决定了执行顺序,先注册的拦截器先执行请求拦截,后执行响应拦截:
// 注册顺序: AuthInterceptor -> LogInterceptor -> ErrorInterceptor
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: LogInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
]
执行流程:
- 请求阶段:AuthInterceptor → LogInterceptor → ErrorInterceptor → 后端
- 响应阶段:ErrorInterceptor → LogInterceptor → AuthInterceptor → 应用代码
注意事项与最佳实践
- 不可变性:始终克隆请求对象而非直接修改,因为
HttpRequest是不可变的 - 依赖注入:拦截器支持依赖注入,但避免循环依赖
- 性能考虑:避免在拦截器中执行耗时操作,影响请求响应速度
- 拦截器范围:在根模块注册的拦截器作用于整个应用,特性模块注册的仅作用于该模块
- 测试策略:使用Angular测试工具packages/core/testing/src/testing.ts测试拦截器逻辑
总结
Angular拦截器通过集中处理HTTP通信逻辑,显著提升了代码复用性和可维护性。本文介绍的认证处理、错误捕获和日志记录等场景只是拦截器能力的冰山一角,你还可以用它实现缓存、请求节流、API版本控制等高级功能。
立即重构你的HTTP请求处理逻辑,体验拦截器带来的开发效率提升吧!更多高级用法可参考Angular官方文档packages/docs/和API参考goldens/public-api/core/。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



