javascript - 为什么nestjs拦截器返回未定义?

标签 javascript node.js typescript interceptor nestjs

我正在尝试在nestjs中实现一个日志拦截器,以便它捕获所有请求和响应并记录它。

因此我实现了这样的 LoggingInterceptor

import { logger } from './../utils/logger';
import { ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import { Observable, BehaviorSubject, from } from 'rxjs';
import { map, tap, refCount, publish, publishLast } from 'rxjs/operators';

    @Injectable()
    export class LoggingInterceptorInterceptor implements NestInterceptor {
      intercept(context: ExecutionContext, call$: Observable<any>): Observable<any> {
        const reqHeaders = context.switchToHttp().getRequest().headers;
        const reqBody = context.switchToHttp().getRequest().body;
        logger.info('Logging the incoming request:',reqHeaders);
        logger.info('Logging the incoming req body:', reqBody);
        const now = Date.now();
        logger.info('Time of request call is', now);

        const serviceBehaviorSubj = new BehaviorSubject<any>(null);

    // response will be available only in the call$ observable stream
    // so use tap to get a clone of the observable and print the data sent

        // this pipe call transforms the response object to start with something called data
        // so a default response like "Done", "test" looks now as a json string 
        // {data : Done}  {data: test}
        // const anotherrespObs: Observable<any> = call$.pipe(publishLast(), refCount());
        // anotherrespObs.pipe(publishLast(), refCount()).subscribe(data => {
        //   logger.info('Logging the outgoing response', data);
        // });

        return call$.pipe(map(data => {
          console.log('data here is', data);
          return ({ dottted: data });
        }));
        //oo.then(return new Pro)
        // return call$.pipe(tap(() => {
        //   logger.info(`Time of completion is ${Date.now() -now}`);
        // }), map(data => {
        //   console.log('ccccccc', data);
        //   return data;
        // }));
      }
}

我知道 call$ 运算符的行为类似于 Observable,并且将由 Nestjs 在内部订阅以将响应发送给客户端,但我想在发送之前记录信息并可能转换响应

所以我利用了rxjs的map()运算符。如果响应集的类型不是“application/json”,则此功能可以正常运行。如果内容类型 是“plain/text”,映射操作将被应用并转换为所需的 json 对象并发送到客户端,但如果响应已经是 application/json 类型(即 json 对象),则不会。我无法应用变换对象。在记录发送到 map() 的值时,我发现它被记录为 json 对象的未定义。那么我如何获取响应(即使它是一个 json 对象)并可能记录它并在将其发送到拦截器中的客户端之前对其进行转换

注意:我担心响应可能包含敏感信息,但我可能会使用日志屏蔽来屏蔽响应数据,但这目前用于测试目的

这是示例 Controller ,我可以在拦截器中记录响应

@ApiOperation({ title: 'Get - With Params', description: 'Test Method with parms' })
@Get('/getTest/:id1/:id2')
@ApiOkResponse({ description: 'Sample string is emitted' })
@ApiResponse({ status: 404, description: 'The endpoint is unavailable' })
@ApiResponse({ status: 503, description: 'The endpoint cannot be processed' })
// @Header('sampleHeaderKey', 'sampleHeaderValue')
// NOte if you send params in the URL and do not use @param then the URL will
// result in NO such end point
public getConfigDataInResponse(@Param('id1') id1: number, @Param('id2') id2: number,  @Req() req) {
  logger.info('request headers', req.headers);
  logger.info('reqiest params', req.params);
  logger.info('reqiest query params', req.query);
  logger.info('reqiest body ', req.body);
  return 'TEST';
}

这是无法记录响应的方法,它在拦截器中显示为“未定义”

public getConfigDataInResponse(@Param('id1') id1: number, @Param('id2') id2: number,  @Req() req, @Res() res) {
  logger.info('request headers', req.headers);
  logger.info('reqiest params', req.params);
  logger.info('reqiest query params', req.query);
  logger.info('reqiest body ', req.body);
  res.set('SampeHeader', 'saomevaluie');
  res.status(HttpStatus.OK).send('some data');
}

最佳答案

当您在 Controller 方法中注入(inject)@Res()时,许多使nest变得如此强大的功能(如拦截器)将不起作用。

<小时/>

在大多数情况下,您不需要注入(inject)@Res(),因为您可以使用专用的装饰器。在您的示例中,这将是:

// Sets the http response code (default for POST is 201, for anything else 200)
@HttpCode(204)
// Sets a custom header
@Header('SampleHeader', 'somevalue')
@Get('/getTest/:id1/:id2')
public getConfigDataInResponse(@Param('id1') id1: number, @Param('id2') id2: number) {
  return 'some data';
}

关于javascript - 为什么nestjs拦截器返回未定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55205145/

相关文章:

node.js - formData 通过 http.post 在 Angular + NodeJS 中

javascript - 可以将 math.max 用于对象数组吗?

javascript - 如何捕获异步非 promise 错误? (对特定错误使用react)

javascript - 单元测试依赖全局事件总线的 Vue 组件

javascript - 如何在 javascript 中使用 uploadcare 限制文件类型?

javascript - 如何覆盖 FilteringSelect dojo 小部件的 onchange 事件的默认行为?

javascript - 为什么我的查询项的 entityAspect 为空?

php - 隐藏 .show 后 JavaScript 出现问题

javascript - 合并的 gulp 任务从不触发 `end` 事件

javascript - node.js 达到 maxSockets 时会发生什么?