Javascript 为什么我的中间件执行了两次?
我在express.js/node.js中编写了一个中间件,用于检查会话,并检查会话是否找到用户ID,显示用户的菜单,或者默认菜单 每个页面请求都会检查id并从数据库中获取用户数据(id、名称、类别等) 以下是中间件:Javascript 为什么我的中间件执行了两次?,javascript,node.js,express,middleware,Javascript,Node.js,Express,Middleware,我在express.js/node.js中编写了一个中间件,用于检查会话,并检查会话是否找到用户ID,显示用户的菜单,或者默认菜单 每个页面请求都会检查id并从数据库中获取用户数据(id、名称、类别等) 以下是中间件: module.exports = function(req,res,next){ console.log("INSIDE SESSION HANDLER"); if(!req.session.uid) return next(); else{
module.exports = function(req,res,next){
console.log("INSIDE SESSION HANDLER");
if(!req.session.uid) return next();
else{
User.get(uid, function(user){
if (!user) {return next(err);}
else{
req.user = res.locals.user = user;
next();
}
})
}
}
然后,ejs检查局部变量,如果有ID,则显示用户的菜单
我正在加载一个测试页面,我没有使用socket.io库,但忘记删除
行
<!DOCTYPE html>
<html>
<head>
<title><%= title %> , <%= settings.title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<script src="/socket.io/socket.io.js"></script>//<== SHOULD DELETE THIS
<h1>Login</h1>
<%include menu%> //<== USES EJS TO CHECK LOCALS AND SHOW DEFAULT OR USER MENU
</head>
<body>
我想真正了解请求/响应和中间件。那么为什么会发生这种情况呢?为什么这个中间件会因为404错误而执行两次?404错误响应是否会导致中间件执行两次
谢谢
编辑
我使用app.js中的中间件,如下所示:
app.use(favicon(__dirname + '/node_modules/static-favicon/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({resave:'false', saveUninitialized:'false', secret:'secret'}));
app.use(express.static(path.join(__dirname, 'public')));
app.set('multimedia', __dirname + '/public/multimedia');
app.use(handler); //<= THE MIDDLEWARE IN QUESTION
app.use(messages);
app.get('/', routes.list);
app.get('/register', register.form);
app.post('/register', register.submitit);
app.use(favicon(uu dirname+'/node\u modules/static favicon/favicon.ico');
应用程序使用(记录器(“开发”);
use(bodyParser.json());
use(bodyParser.urlencoded({extended:false}));
使用(cookieParser());
使用(会话({resave:'false',saveUninitialized:'false',secret:'secret'}));
app.use(express.static(path.join(uu dirname,'public'));
app.set('multimedia','u dirname+'/public/multimedia');
应用程序使用(处理程序)// 你在哪里应用这个中间件
例如,如果你有
app.use(handler)
如果处理程序
的形式为函数(req、res、next)
,则它将应用于每个请求(使用任何HTTP动词)。或者
app.get('/some/route', handler)
其中处理程序
将应用于/some/route
下面的任何地方(例如/some/route/any/deepness
)
因此,我的猜测是,您过度应用了中间件功能(我正在交换处理程序和中间件,它们具有相同的函数签名-也许处理程序更适合于向调用next()
的人发送响应和中间件的函数)。但是很难说没有这个中间件是如何应用的
请参阅和Express提供的其他指南
另外,您不需要在中间件中返回next()
。只需next()
中间件运行两次的原因是,它运行一次用于初始请求,一次用于404(不存在的静态脚本)
如果express.static
可以找到一个文件,它将发送相应文件的响应,如果找不到正确的文件(就像您的情况一样),它将调用next()
,尝试将请求与其他路由匹配,运行下面定义的任何其他中间件express.static
换句话说,如果express.static
确实找到了要提供服务的文件,那么它下面的中间件将不会运行。在您的情况下,中间件为实际请求运行一次,并尝试查找文件或正确的路由作为响应
这可以通过记录正常静态文件和不存在的静态文件的req.path
来观察:
app.js-
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req, res, next){
console.log('Requested path: %s', req.path);
next();
})
layout.hbs(为“/”呈现)-
希望这能有所帮助。我更新了我的问题,展示了如何在app.js
中定义中间件。很好的回答,我明白你的意思,但我不认为我用得太多,因为我定义了它,然后它后面的其他定义都使用了它。这与404错误和中间件执行两次有什么关系?Thanks@slevin当您请求不存在的文件时,中间件会运行(因为它运行在非静态的所有文件上),然后是打印404页面的404处理程序。可能是express.static
无法为请求的文件提供服务,因此它会继续请求链(也称为“next()
”),在这种情况下,它将运行app.use(handler)
中间件,并尝试与下面的其他路由匹配,没有一个路由适用,因此它显示404。换句话说,它记录了一次实际的页面加载,一次记录404。在测试了这种情况后,我在下面的回答中写了上面的评论。非常感谢您的回答。我猜在第三段的第一行中,对文件是否有好处
您的意思是是否找到了文件
?
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req, res, next){
console.log('Requested path: %s', req.path);
next();
})
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<link rel='stylesheet' href='/stylesheets/style.css' /> <!-- exists -->
<link rel='stylesheet' href='/stylesheets/foo.css' /> <!-- doesn't exist -->
</head>
<body>
{{{body}}}
</body>
</html>
Requested path: /
Requested path: /stylesheets/foo.css