javascript - 如何在 NestJS 中记录所有 Axios 外部 http 请求
问题描述
我希望能够使用完整的 url、标头等记录每个 axios 请求,但目前没有找到这样做的方法。
到目前为止,我所做的是根据这个答案编写一个 Http Interceptor
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 调用。
有什么想法吗?
那是context
对象:
args:Array(2) [IncomingMessage, ServerResponse]
constructorRef:class AppController { … }
getRequest:() => …
getResponse:() => …
handler:data() { … }
__proto__:Object {constructor: , getClass: , getHandler: , …}
即req
:
_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
解决方案
Nest.js-Interceptors 只处理控制器处理的请求和响应。如果在处理控制器请求时使用 Axios 发出 http 请求,它们将不会被拦截器处理。
Axios 拦截器
直接通过HttpService
暴露其axios
实例get axiosRef()
。有了它,您可以添加axios interceptor
:
this.httpService.axiosRef.interceptors.request.use(config => { /*...*/ return config })
onModuleInit()
例如,您可以在AppModule
.
代表门面
作为替代方案,您可以创建一个HttpService
外观,记录请求并将所有调用委托给内置HttpService
:
@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
.
推荐阅读
- c++ - 我可以在另一个 .hpp 文件中包含多个 .hpp 文件吗?
- python - 在时间 t-1 和时间 t Python Pandas 匹配面板数据
- firebase - 是否可以向 Firebase Firestore 规则添加评论?
- c# - 实体框架核心 HasOne 和 WithMany 不存在
- javascript - 树状复选框和角度搜索过滤器实现?
- quarkus - 如何告诉 quarkus 从一个随机的自由端口开始?以及如何读取分配的端口号?
- javascript - JQuery可折叠菜单问题
- phpmailer - PHPMailer 雅虎 SMTP 连接失败
- sql - SQL Server 中每条记录的百分比
- capl - 如何在不使用 CDD 填充的情况下通过 CAPL 发送 UDS 消息