【发布时间】:2016-01-18 19:58:07
【问题描述】:
我在 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{
User.get(uid, function(user){
if (!user) {return next(err);}
else{
req.user = res.locals.user = user;
next();
}
})
}
}
然后,ejs 会检查 locals,如果有 ID,则显示用户的菜单。
我正在加载一个没有使用 socket.io 库的测试页面,但忘记删除 <script src="/socket.io/socket.io.js"></script> 行。
<!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>
当script src 行不存在时,中间件执行一次(只看到一次console.log("INSIDE SESSION HANDLER");)。
当script src 行出现时,显然给出了 404 错误,但中间件执行了两次(两次看到了console.log("INSIDE SESSION HANDLER");)。
这是console.log的输出:
INSIDE SESSION HANDLER
GET / 304 66ms //page
GET /stylesheets/style.css 304 11ms
INSIDE SESSION HANDLER //again
GET /socket.io/socket.io.js 404 28ms - 1.04kb
GET /multimedia/01.jpg 304 4ms //images...
GET /multimedia/02.jpg 304 5ms
我想真正了解请求/响应和中间件。那么为什么会这样呢?为什么这个中间件会因为 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);
【问题讨论】:
-
可能是
express.static无法提供所请求的文件,因此它继续请求链(又名'next()'),在这种情况下它将运行app.use(handler)中间件并尝试与较低的其他路由匹配,不适用,因此它显示 404。换句话说,它为实际页面加载记录一次,为 404 记录一次。 -
在测试了这种情况后,我已将上述评论写在下面的答案中。
标签: javascript node.js express middleware