Angular 拦截器教程
概述
在 Angular 应用中,拦截器(Interceptor)是一个强大的工具,用于拦截和处理 HTTP 请求和响应。拦截器可以用于多种用途,如添加认证头、处理错误、缓存响应等。本教程将详细介绍 Angular 拦截器的概念、使用方法以及如何在实际项目中应用它们。
1. 拦截器的基本概念
1.1 什么是拦截器?
拦截器是 Angular 提供的一种机制,允许你在 HTTP 请求发送之前或响应返回之后对其进行拦截和处理。拦截器可以用于修改请求或响应,或者在请求或响应过程中执行一些额外的逻辑。
1.2 拦截器的用途
- 认证和授权:在请求头中添加认证令牌。
- 错误处理:统一处理 HTTP 错误。
- 日志记录:记录请求和响应的详细信息。
- 缓存:缓存响应以提高性能。
- 请求重试:在请求失败时自动重试。
2. 创建一个简单的拦截器
2.1 创建拦截器类
首先,我们需要创建一个拦截器类。拦截器类需要实现 HttpInterceptor 接口,并定义 intercept 方法。
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// 在这里添加认证逻辑
const authToken = 'your-auth-token';
const authReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${authToken}`)
});
return next.handle(authReq);
}
}
2.2 注册拦截器
拦截器需要在 Angular 模块中注册。通常,我们会在 AppModule 中注册拦截器。
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';
@NgModule({
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
]
})
export class AppModule { }
2.3 使用拦截器
一旦拦截器被注册,所有通过 HttpClient 发送的请求都会被拦截。你可以在 intercept 方法中添加任何你需要的逻辑。
3. 拦截器的实践应用
3.1 添加认证头
在实际应用中,你可能需要为每个请求添加一个认证令牌。以下是一个示例:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authToken = localStorage.getItem('authToken');
if (authToken) {
const authReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${authToken}`)
});
return next.handle(authReq);
}
return next.handle(req);
}
3.2 错误处理
你可以使用拦截器来统一处理 HTTP 错误。例如,当请求失败时,你可以显示一个错误消息。
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((error: any) => {
console.error('HTTP Error:', error);
return throwError(error);
})
);
}
3.3 请求重试
在某些情况下,你可能希望在请求失败时自动重试。你可以使用 retry 操作符来实现这一点。
import { retry } from 'rxjs/operators';
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
retry(2) // 重试两次
);
}
4. 实践练习
4.1 创建一个日志拦截器
创建一个拦截器,用于记录所有 HTTP 请求和响应的详细信息。你可以使用 console.log 来记录这些信息。
import { tap } from 'rxjs/operators';
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('Request:', req);
return next.handle(req).pipe(
tap(event => {
console.log('Response:', event);
})
);
}
4.2 实现一个缓存拦截器
创建一个拦截器,用于缓存 GET 请求的响应。你可以使用 localStorage 或 sessionStorage 来存储缓存数据。
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.method === 'GET') {
const cachedResponse = localStorage.getItem(req.url);
if (cachedResponse) {
return new Observable(observer => {
observer.next(JSON.parse(cachedResponse));
observer.complete();
});
}
}
return next.handle(req).pipe(
tap(event => {
if (event instanceof HttpResponse && req.method === 'GET') {
localStorage.setItem(req.url, JSON.stringify(event));
}
})
);
}
5. 总结
拦截器是 Angular 中一个非常强大的工具,可以帮助你统一处理 HTTP 请求和响应。通过本教程,你应该已经掌握了如何创建和使用拦截器,以及如何在实际项目中应用它们。拦截器的灵活性使得它们可以用于多种用途,如认证、错误处理、日志记录和缓存等。
6. 进一步学习
- 多拦截器:Angular 支持多个拦截器,你可以按顺序注册它们,并按顺序执行。
- 异步操作:拦截器可以执行异步操作,如从服务器获取认证令牌。
- 高级主题:探索如何使用拦截器实现更复杂的逻辑,如请求合并、响应转换等。
通过不断实践和学习,你将能够更好地利用 Angular 拦截器来提升应用的性能和安全性。