Express.js: app.locals与res.locals与req.session的区别

21

我试图理解什么时候最好使用以下各项。这是我的初步理解:

app.locals -- 适用于在应用程序级别存储全局变量。所有用户/会话将看到这些变量的相同值,这些变量可供所有视图使用。

res.locals -- 适合为特定的请求/响应周期存储变量。这些变量仅在与响应关联的视图中可用。

req.session -- 适合存储与唯一用户会话相关的变量(例如用户名)。这些变量应该对唯一用户/会话的所有视图都可用。

我具体的用例如下:用户运行查询从mongodb检索数据。现在,我希望这个查询的结果(一个JSON数组)作为一个变量在所有的视图(HTTP请求)中都可用。最好的方法是“存储”结果数组,以便每个视图都可以访问它?


你基本上已经回答了这个问题。req.locals 用于在当前请求的视图中可用的数据。 - Andreas Hultgren
1个回答

5
我现在想要这个查询的结果,它是一个json数组,可以作为所有视图的变量使用。最好的方法是什么,以便"存储"结果数组,以便每个视图都可以访问它?
当你说"可供所有视图使用"时,我认为你指的是跨所有HTTP请求。如果是这样的话,那么你需要知道HTTP是一种无状态协议,不提供此功能。您需要开发自己的机制来实现此目的。
一种方法是在服务器上缓存此信息(数组),并在每个请求中检索它(例如,从内存而不是从MongoDB中检索它)。您将在cookie上存储会话ID,并基于此ID在另一个请求到达时从缓存中获取它。有几个可用的缓存工具(例如redis,memcached等),您可以选择将信息存储在内存中。
您还可以将此信息(数组本身)放入cookie中,在这种情况下,它将在每个HTTP请求之间来回发送到客户端和服务器,并且很可能不是一个非常好的主意,除非数据非常小。

1
如果您将数据存储在 app.locals 中,并且不运行多个 Node 进程(即不使用 cluster),则即使在多次请求中,它也可用于所有视图。 - robertklep
@robertklep -- 这就是我最初所做的,将数据存储在app.locals中,但后来我使用两台PC进行HTTP请求测试,它们都看到了相同的数据!我不想在客户端之间共享数据。 - user2001702
2
所以你想让它们在所有视图中都可用,但仅限于触发查询的用户?使用 req.session(再次,在你的问题中你已经自己回答了;-) - robertklep
1
@JasonGelinas 如果你将它存储在app.locals中,你需要存储与之关联的“会话ID”,以便在下一个请求中获取该特定值。 - Hector Correa
@robertklep -- 你能解释一下使用app.locals和PM2这样的集群模块存在的问题吗?为什么app.local的值不会对所有进程都可用? - user2400026
2
在这种情况下,用户想要触发一个MongoDB查询(并存储其结果),我假设这将在Express应用程序已经启动和运行时发生。如果您使用cluster(或者基本上是fork())来处理Express路由,那么一个子进程中对app.locals的更改不会反映在其他子进程中。 - robertklep

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接