[英]Nestjs Error: Cannot set headers after they are sent to the client
I have a global middleware and a global guard, when request goes into the guard it apparently sends a response(the request doesn't get to the controllers), which is strange because the client gets 404, and nestjs throws an error "Cannot set headers after they are sent to the client".我有一个全局中间件和一个全局守卫,当请求进入守卫时,它显然会发送响应(请求没有到达控制器),这很奇怪,因为客户端得到 404,并且nestjs 抛出错误“无法设置发送到客户端后的标头”。 If I disable the middleware everything works fine.如果我禁用中间件,一切正常。 How can i fix this?我怎样才能解决这个问题?
Middleware:中间件:
@Injectable()
export class AuthMiddleware implements NestMiddleware {
@Inject()
private readonly usersService: UsersService;
@Inject()
private readonly tokenService: TokenService;
async use(req: Request, res: Response, next: NextFunction): Promise<void> {
if (!req.cookies.token) {
req.user = {
userId: null,
personId: null,
role: null,
};
next();
}
try {
const result = this.tokenService.verifyToken(req.cookies.token);
const user = await this.usersService.findOne(result.userId);
if (!user) {
req.user = {
userId: null,
personId: null,
role: null,
};
next();
}
req.user = {
userId: result.userId,
personId: result.personId,
role: result.role,
};
} catch {
req.user = {
userId: null,
personId: null,
role: null,
};
}
next();
}
}
Guard:警卫:
@Injectable()
export class RoleGuard implements CanActivate {
constructor(private reflector: Reflector) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const req: Request = await context.switchToHttp().getRequest();
const requiredRole = this.reflector.get<Roles | null>(
'requiredRole',
context.getHandler(),
);
if (!requiredRole) {
return true; // everything breaks here
}
if (
requiredRole !== req.body.user.role &&
req.body.user.role !== Roles.ADMIN
) {
return false;
}
return true;
}
}
main.ts: main.ts:
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(cookieParser());
app.use(urlencoded({ extended: true }));
app.useGlobalPipes(
new ValidationPipe({
transform: true,
}),
);
app.useGlobalGuards(new RoleGuard(new Reflector()));
await app.listen(3000);
}
bootstrap();
app.module.ts: app.module.ts:
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: '.env',
}),
TypeOrmModule.forRoot(getOrmConfig()),
UserModule,
EventModule,
],
controllers: [],
providers: [RoleGuard],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(AuthMiddleware).forRoutes({
path: '*',
method: RequestMethod.ALL,
});
}
}
Somehow I managed to fix it by deleting this from AuthGuard:不知何故,我设法通过从 AuthGuard 中删除它来修复它:
if (!req.cookies.token) {
req.user = {
userId: null,
personId: null,
role: null,
};
next();
}
Maybe someone knows why it worked?也许有人知道它为什么起作用?
I suppose it happens due to inappropriate next()
function call implementation.我想这是由于不适当的next()
函数调用实现而发生的。
The error you are getting is because after calling next()
, you have some additional code to run which will call next()
which will cause your controller to send a response back to the client, but it was already sent by your first call.你得到的错误是因为在调用next()
之后,你有一些额外的代码要运行,它将调用next()
这将导致你的控制器将响应发送回客户端,但它已经在你的第一次调用中发送。
To fix current realisation simple change next()
- > to return next()
here more info about it要修复当前实现,只需更改next()
- > 以在此处return next()
的更多信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.