代码之家  ›  专栏  ›  技术社区  ›  Sergino

如何在NestJS中记录所有AXIOS外部HTTP请求

  •  0
  • Sergino  · 技术社区  · 7 年前

    我希望能够用完整的URL、头等记录每个AXIOS请求,但目前没有找到这样做的方法。

    到目前为止,我所做的是基于此编写一个HTTP拦截器 answer

    export class HttpLoggerInterceptor 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
            const req = context.switchToHttp().getRequest();
            return data;
          }),
        );
      }
    }
    

    现在我浏览对象 req context 在调试上的道具,但看不到ASIOS请求URL等,除非我错过了。

    我的控制器路由( api/data 在这种情况下)有n个HTTP外部调用发生,但拦截器只截取控制器调用,而不截取AXIOS调用。

    有什么想法吗?

    那就是 语境 对象:

    args:Array(2) [IncomingMessage, ServerResponse]
    constructorRef:class AppController { … }
    getRequest:() => …
    getResponse:() => …
    handler:data() { … }
    __proto__:Object {constructor: , getClass: , getHandler: , …}
    

    那就是 情商 :

    _dumped:false
    _events:Object {}
    _eventsCount:0
    _maxListeners:undefined
    _parsedOriginalUrl:Url {protocol: null, slashes: null, auth: null, …}
    _parsedUrl:Url {protocol: null, slashes: null, auth: null, …}
    _readableState:ReadableState {objectMode: false, highWaterMark: 16384, buffer: BufferList, …}
    baseUrl:""
    body:Object {}
    client:Socket {connecting: false, _hadError: false, _handle: TCP, …}
    complete:true
    connection:Socket {connecting: false, _hadError: false, _handle: TCP, …}
    destroyed:false
    fresh:false
    headers:Object {accept: "application/json, text/plain, */*", user-agent: "axios/0.18.0", host: "localhost:3000", …}
    host:"localhost"
    hostname:"localhost"
    httpVersion:"1.1"
    httpVersionMajor:1
    httpVersionMinor:1
    ip:"::ffff:127.0.0.1"
    ips:Array(0)
    method:"GET"
    next:function next(err) { … }
    originalUrl:"/api/data"
    params:Object {}
    __proto__:Object {constructor: , __defineGetter__: , __defineSetter__: , …}
    path:"/api/data"
    protocol:"http"
    query:Object {}
    rawHeaders:Array(8) ["Accept", "application/json, text/plain, */*", "User-Agent", …]
    rawTrailers:Array(0) []
    readable:true
    readableBuffer:BufferList
    readableFlowing:null
    readableHighWaterMark:16384
    readableLength:0
    res:ServerResponse {_events: Object, _eventsCount: 1, _maxListeners: undefined, …}
    route:Route {path: "/api/data", stack: Array(1), methods: Object}
    secure:false
    socket:Socket {connecting: false, _hadError: false, _handle: TCP, …}
    stale:true
    statusCode:null
    statusMessage:null
    subdomains:Array(0)
    trailers:Object {}
    upgrade:false
    url:"/api/data"
    xhr:false
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Kim Kern    7 年前

    nest.js-interceptors只处理由控制器处理的请求和发出的响应。如果在处理控制器请求时使用AXIOS发出HTTP请求,拦截器将不会处理这些请求。


    AXIOS拦截器

    这个 HttpService 暴露其 axios 实例直接通过 get axiosRef() . 使用它,您可以添加 axios interceptor :

    this.httpService.axiosRef.interceptors.request.use(config => console.log(config));
    

    例如,您可以在 onModuleInit() 你的 AppModule .


    委托给门面

    作为替代方案,您可以创建 HTTP服务 Facade,它记录请求并将所有调用委托给内置的 HTTP服务 :

    @Injectable()
    export class MyHttpService {
      private logger: Logger = new Logger(MyHttpService.name);
    
      constructor (private httpService: HttpService) {}
    
      public get<T = any>(url: string, config?: AxiosRequestConfig): Observable<AxiosResponse<T>> {
        this.logger.log({url, config});
        return this.httpService.get(url, config)
           .pipe(tap(response => this.logger.log(response)));
      }
    
      // ... all the other methods you need.
    
    }
    

    你可以自己创造 LoggingHttpModule 内置的 HttpModule 并将您的 MyHttpService .

    推荐文章