nestjs 拦截和修改传出的 http 请求

Dan*_*ier 8 http typescript nestjs

所以我很可能错过了什么或做错了什么。我有一个 NestJS 应用程序,它试图向外部 API 发出 http 请求。我希望能够在执行它之前拦截这个传出请求并修改它的标头。

我试过使用拦截器无济于事,传入的http请求被拦截,但传出的请求没有被拦截。任何建议或帮助将不胜感激。

jue*_*hus 7

我在修改/添加响应头时遇到了类似的问题。以下代码对我有用:

@Injectable()
export class TransformHeadersInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<any>,
  ): Observable<any> {

    return call$.pipe(
            map((data) => {
                // pipe call to add / modify header(s) after remote method
                let req = context.switchToHttp().getRequest();
                req.res.header('x-api-key', 'pretty secure');
                return data;
            }),
        );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 可能想要添加 ` const res = context.switchToHttp().getResponse(); if (!res.headersSent) { // for res.redirect()` (2认同)
  • 这似乎没有为我添加任何标题。 (2认同)

Upv*_*ote 6

我们先来处理

我试过使用拦截器无济于事,传入的http请求被拦截,但传出的请求没有被拦截。

根据文档https://docs.nestjs.com/interceptors应该完全有可能拦截响应。

@Injectable()
export class TransformHeadersInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<any>,
  ): Observable<any> {
    // Get request headers, e.g.
    const userAgent = context.switchToHttp().getRequest().headers['user-agent'];

    // Not sure if headers are writeable like this, give it a try
    context.switchToHttp().getResponse().headers['x-api-key'] = 'pretty secure';

    return call$;
  }
}
Run Code Online (Sandbox Code Playgroud)

如果要根据响应数据操作标头。您可以像这样利用数据:

return call$.pipe(map(data => {
    // Your code here
    return data;
}));
Run Code Online (Sandbox Code Playgroud)

我有一些想法:

我有一个 NestJS 应用程序,它试图向外部 API 发出 http 请求。我希望能够在执行它之前拦截这个传出请求并修改它的标头。

所以我认为有两个用例。首先,您有一组默认标头,这些标头最初分配给 http 客户端并随每个请求一起发送。例如:

import { HTTP_TOKEN } from './constants';
import * as http from 'request-promise-native';

export const httpProviders: any = [
  {
    provide: HTTP_TOKEN,
    useFactory: () => {
      return http.defaults({
        headers: {
          'Accept': 'application/json',
          'Content-type': 'application/json',
          'User-agent': 'my--app',
        },
      });
    },
  },
];
Run Code Online (Sandbox Code Playgroud)

其次,您为每个请求创建和分配标头。这是你使用拦截器的时候。在身份验证的上下文中,您可以考虑使用警卫,就像 tano 在他的回答中建议的那样。