简体   繁体   English

Nestjs 错误:将标头发送到客户端后无法设置标头

[英]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.

相关问题 将标头发送到客户端后无法设置标头 - 错误 - Cannot set headers after they are sent to the client - error 发送到客户端错误后无法设置标头 - Cannot set headers after they are sent to the client error 发布请求后出现“发送到客户端后无法设置标头”错误 - “Cannot set headers after they are sent to the client” error after post request 错误:在快递中间件中将标头发送回客户端后无法设置标头 - Error: Cannot set headers after they are sent back to the client in express middleware 将标头发送到客户端后无法设置标头 node.js 中的错误 - Cannot set headers after they are sent to the client Error in node.js Mongodb 错误:发送到客户端后无法设置标头 - Mongodb error: Cannot set headers after they are sent to the client 在快速js中将它们发送到客户端错误后无法设置标头 - getting Cannot set headers after they are sent to the client error in express js Express 错误:发送到客户端后无法设置标头 - Express Error: Cannot set headers after they are sent to the client 收到错误消息:将标头发送到客户端后无法设置标头 - Getting an error: cannot set headers after they are sent to the client 表单数据错误在发送到客户端后无法设置标题 - Form data Error Cannot set headers after they are sent to the client
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM