拦截器

拦截器具有一系列有用的功能,这些功能受面向切面编程(AOP)技术的启发,它们可以:

  • 在函数执行之前/之后绑定额外的逻辑
  • 转换从函数返回的结果
  • 转换从函数抛出的异常
  • 扩展基本函数行为
  • 根据所选条件完全重写函数,例如缓存目的

响应拦截器

场景:使后端返回一个标准的json格式,方便前端进行逻辑判断,这需要给数据做一个全局format

1
2
3
4
5
6
{
data, //数据
status:0,
message:"成功",
success:true
}

编写拦截器common/response.ts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import {
Injectable,
NestInterceptor,
CallHandler,
ExecutionContext,
} from '@nestjs/common';
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';

interface Data<T> {
data: T;
}

@Injectable()
export class Response<T> implements NestInterceptor {
intercept(
context: ExecutionContext,
next: CallHandler<any>,
): Observable<Data<T>> | Promise<Observable<Data<T>>> {
// Nestjs配合Rxjs格式化数据
return next.handle().pipe(
map((data) => {
return {
data,
status: 0,
message: '成功',
success: true,
};
}),
);
}
}

在main.ts注册拦截器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { NestFactory } from '@nestjs/core';
import { VersioningType } from '@nestjs/common';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';
import { Response } from './common/response';

async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
cors: true,
});
app.enableVersioning({
type: VersioningType.URI,
});
// 注册拦截器
app.useGlobalInterceptors(new Response());
await app.listen(3000);
}
bootstrap();

接口数据成功被格式化了:

异常过滤器

场景:后端的接口相关异常需要集中捕获,并返回错误信息:

1
2
3
4
5
6
7
{
success: false,
time: new Date(),
data: exception.message,
status,
path: request.url,
}

编写过滤器common/filter.ts:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';

// 捕获异常需要用@Catch装饰器
// 可以给@Catch指定异常的类型
@Catch(HttpException)
export class HttpFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
// 获取http上下文
const ctx = host.switchToHttp();

const request = ctx.getRequest<Request>();
const response = ctx.getResponse<Response>();
const status = exception.getStatus();
// 返回错误信息
response.status(status).json({
success: false,
time: new Date(),
data: exception,
status,
path: request.url,
});
}
}

在main.ts注册过滤器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { NestFactory } from '@nestjs/core';
import { VersioningType } from '@nestjs/common';
import { AppModule } from './app.module';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { HttpFilter } from './common/filter';

async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
cors: true,
});
app.enableVersioning({
type: VersioningType.URI,
});
// 注册过滤器
app.useGlobalFilters(new HttpFilter());
await app.listen(3000);
}
bootstrap();

异常信息成功被返回了: