middleware, 中间件是一个特殊的url地址处理函数,它被当作 app.use(中间件函数) 的参数或者是某个路由处理函数中使用。
中间件是 express 的最大特色,也是最重要的一个设计。Express是一个自身功能极简,完全是路由和中间件构成一个web开发框架:从本质上来说,一个Express应用就是在调用各种中间件一个 express 应用,就是由许许多多的中间件来完成的
中间件是一个函数 中间件肯定不止一个,多个中间件按顺序执行
中间件-基本使用
// 具名函数格式:
const handler1 = (req, res, next) => {
console.log(Date.now());
next();
}
app.use(handler1);
// 匿名函数格式:
app.use((req, res, next) => {
console.log(Date.now());
next();
});
中间件函数中有三个基本参数, req、res、[next]
req就是请求相关的对象,它和下一个中间件函数中的req对象是一个对象
res就是响应相关的对象,它和下一个中间件函数中的res对象是一个对象
next:它是一个函数,调用它将会跳出当前的中间件函数,执行后续中间件;如果不调用next,也不执行res.end,则整个请求都会在当前中间件卡住
const express = require('express')
const app = express();
app.use((req, res, next) => {
console.log("第1个中间件");
res.setHeader('content-type', 'text/html;charset=utf8');
res.a1 = 100; // 属于一个动作 res 里的东西会跟随这向下传递下面 顺序执行
next(); // 向下继续进行
});
app.use((req, res, next) => {
console.log("第2个中间件");
req.a2 = 200;
next(); //
});
app.use((req, res, next) => { // 直接在这个位置结束 下面的就不要了 请求不到请求
console.log("第3个中间件");
req.a3 = 300;
console.log(req.a1, req.a2)
res.end('中间件'); /* 碰见 res.end 就结束了 没有 next或者没有res.end()
他就会在请求的时候卡住 */
});
// 如果走到头 还是用 next() 这样会报错找不到地址
app.listen(3000, () => {
console.log('express应用在3000端口启动了');
})
路由匹配有四种模式
1.app.use(中间件)是应用级中间件,所有的请求都能匹配。
2. app.use('/apiname',中间件) 。匹配请求路径是/apiname的请求。
3. app.get('/apiname',中间件) 。匹配get类型并且请求路径是/apiname的请求,就是我们前面说的路由。
4. app.post('/apiname',中间件1,中间件2) 。一个路由中使用多个中间件。
中间件的应用-访问日志
function getClientIp(req) { // 虎丘
return req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;
}
app.use((req,res,next) => {
console.log('我来用记录访问日志')
// 获取当前用户访问的页面地址: req.url
// 获取当前用户的id的地址: ?
// 当前时间
const dt = new Date()
console.log('来自:', getClientIp(req));
console.log('时间',dt.toLocaleTimeString())
console.log('访问',req.url)
})