使用Express中间件进行按请求模块配置?

时间:2015-10-23 19:47:13

标签: node.js express concurrency thread-safety middleware

让我们说我的应用程序的每个请求都包含一个MAGIC标头,我想在某处注入该标头值,而不更新我的所有请求方法。听起来它是中间件的工作,对吗?

但这会是线程安全的吗?有一种方法可以在一个多个请求可以在同一时间飞行的世界中使用Express中间件吗?

换句话说,我询问示例代码中的Express中间件是否正在设置全局共享变量,或者每个请求是否由独立线程处理,其中myconfig是每个单独的隔离副本请求。

示例代码:

var assert = require('assert');
var sleep = require('sleep');

var express = require('express');
var app = express();

var myconfig = {};

app.use(function(req, res, next) {
  myconfig.MAGIC = req.headers['MAGIC'];
  next();
});

app.get('/test', function(req, res) {
  // Pause to make it easy to have overlap.
  sleep(2);
  // If another request comes in while this is sleeping,
  // and changes the value of myconfig.MAGIC, will this
  // assertion fail?
  // Or is the copy of `myconfig` we're referencing here
  // isolated and only updated by this single request?
  assert.equal(myconfig.MAGIC, req.headers['MAGIC']);
});

1 个答案:

答案 0 :(得分:2)

将为每个请求执行任何中间件功能。使用中间件设置某些内容的值时,通常最好将其设置为app.localsres.locals,具体取决于您希望数据的持久性。以下是两者的良好比较:https://stackoverflow.com/a/14654655/2690845

app.use(function(req, res, next) {
  if (req.headers['MAGIC']) {
    app.locals.MAGIC = req.headers['MAGIC'];
  }
  next();
});
...
app.get('/test', function(req, res) {
  assert.equal(app.locals.MAGIC, req.headers['MAGIC']);
});