NodeJS 在任何位置访问请求上下文

nqwrtyyt  于 2023-01-08  发布在  Node.js
关注(0)|答案(3)|浏览(109)

我正在使用Express,每次使用日志调试和跟踪应用程序时,我都需要访问请求中的一些数据(标头、Cookie等)。
使用其他语言(即:Java)我有一个“线程上下文”,我可以把数据放在那里,所以每当我记录一些东西时就可以访问它。但是就我所知,NodeJS没有这样的东西,因为我们只有一个线程。
我试图避免在每个函数中传递req变量,以便记录该信息。
是否有node或expressjs特性可以让我从任何地方获取数据?

7cwmlq89

7cwmlq891#

    • 更新**:节点最近将此功能作为本机功能引入:AsyncLocalStorage类似于其他语言中的线程本地存储。

https://nodejs.org/api/async_context.html

    • 旧答案**

看看Continuation Local Storage,它实现了类似于异步调用链的线程上下文的东西:https://github.com/othiym23/node-continuation-local-storage
还有一些人试图将异步本地存储作为一个标准化特性构建到JavaScript本身中,但他们仍然处于非常早期的阶段:TC39分区建议https://docs.google.com/presentation/d/1H3E2ToJ8VHgZS8eS6bRv-vg5OksObj5wv6gyzJJwOK0

fhg3lkii

fhg3lkii2#

AsyncLocalStorage维护一个独立的存储上下文,这可能是在请求生命周期的后续函数中访问请求上下文的方式(仅当req未传递给异步函数时)。
以下是将值推送到AsyncLocalStorage的方法:

const asyncStorage = new AsyncLocalStorage();

const requestLoggerMiddleWare = (req, res, next) => {
  asyncStorage.run(new Map(), () => {
    asyncStorage.getStore().set('key', req.get('example-header'));
    next();
  });
};

app.use(requestLoggerMiddleWare)

在异步函数调用被解析之前,此值可以在任何函数中使用。

const exampleHeader = asyncStorage.getStore().get('example-header');
osh3o9ms

osh3o9ms3#

JavaScript是单线程的这一事实并不是一个限制,也不妨碍使用“线程上下文”作为使用“普遍可访问状态”的一种手段。一旦进行异步调用,状态不再符合您的预期,问题就会出现。
这就是为什么全局状态被认为是“坏习惯”的原因之一,您应该努力避免它(尤其是在JavaScript和/或Node中开发时...)。
相反,你应该传递一个对象,而不是req。你应该构造你的对象或调用你的函数,这样与每个调用链相关的log示例(从请求事件开始并通过所有内部调用)。应该使用日志记录所需的任何上下文初始化log示例,在您的情况下,来自原始req的请求细节。

相关问题