express中间件
- 特点
- 高阶函数,可以访问请求对象,响应对象,
- 在web应用中处于请求–响应循环流程中的中间件,被命名为变量next
- 若无终结,必须调用next()方法将控制权交给下一中间件,否则请求会被挂起
- 功能
- 修改请求和响应对象
- 终结请求–响应循环体
- 调用堆栈中的下一个中间件
代码示例
// main.js
var express = require('express')
var app = express()
var logger = require('./logger')
app.use(logger('LOG: '))
// 定义应用根目录
app.use(express.static('.'))
// 应用cookie解析
var cookieParser = require('cookie-parser')
app.use(cookieParser())
var exSession = require('./exSession')
app.use(exSession({
// 对会话进行加密的密钥
secret: "recommand 128 bytes random string",
cookie: {
// cookie最大存活其60秒
maxAge: 60 * 1000
},
resave: false,
saveUninitialized: true
}))
var ejs = require('ejs')
// 设置模板目录
app.set('views', __dirname)
// 设置模板引擎
app.set('view engine', 'ejs')
// 模拟数据库
var users = {
'root': 'root',
'guest': '123456',
};
function auth(user, password) {
return users.hasOwnProperty(user) && users[user] == password;
}
app.get('/', function (req, res) {
var session = req.session;
if (session.hasLogin) {
session.visitCount++;
res.render('stat', session);
} else {
res.render('login', session);
}
});
app.get('/login', function (req, res) {
var user = req.query.user;
var password = req.query.password;
if (auth(user, password)) {
var session = req.session;
session.hasLogin = true;
session.user = user;
session.visitCount = 0;
res.redirect('/');
} else {
res.render('failed', {});
}
})
app.get('/logout', function (req, res) {
var session = req.session;
session.destroy(function (err) {
res.redirect('/');
});
})
app.get('/show', function (req, res) {
var session = req.session;
if (session.hasOwnProperty('visitCount'))
session.visitCount++;
else
session.visitCount = 0;
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.write('<h1>' + session.visitCount + '</h1>');
res.end();
});
app.get('/del', function (req, res) {
var session = req.session;
session.destroy(function (err) {
console.log('del session');
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.write('<h1>Del Session</h1>');
res.end();
});
});
app.listen(8085)
// exSession.js
var sessions = {}
// 实现session的构造函数
function Session(sid) {
this.$sid = sid;
// 实现中间件接口
this.destroy = function (callback) {
// 删除指定的session对象
delete sessions[this.$sid]
callback(null)
}
}
// 创建生成SID函数
function createSID() {
var chars = "0123456789"
var length = chars.length
var sid = 'sid-'
for (var i = 0; i < length; i++) {
// 获取随机数
var number = Math.floor(Math.random() * length)
sid += number;
}
return sid
}
// 根据SID查找对应的Session,不存在则生成session实例并返回
function getSession(req, res) {
var sid
// 存在sessionid则获取,不存在则创建,并写入响应对象
if (req.cookies.sid) {
sid = req.cookies.sid
} else {
sid = createSID()
res.cookie('sid', sid)
}
var session
if (sessions[sid]) {
session = sessions[sid]
} else {
session = new Session(sid)
// 有session对象入库,构成了一个小型的内存数据库
sessions[sid] = session
}
return session
}
// 导出中间件
module.exports = function (options) {
function middleware(req, res, next) {
// 后续的是间件可以直接访问req.session获得Session对象
req.session = getSession(req, res)
next()
}
return middleware
}