中间件的概念:
用以封装,处理http请求的细节,让我们去处理业务逻辑而不是底层的一些繁琐细节
nodejs中的中间件工作:
例如下面的代码:
var router = require('./router')
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
var fs = require('fs')
app.use('/node_modules/', express.static('./node_modules/'))
app.use('/public/', express.static('./public/'))
app.engine('html', require('express-art-template'))
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(router)
app.listen(3000, function() {
console.log("running at 3000");
})
其中的use
,engine
就是内置的一些中间件,它对传入的目录/文件/等等,进行处理并返回方法
中间件的分类:
应用程序级别中间件:
var express = require('express')
var app = express()
// 中间件:处理请求,本质就是个处理函数
// 在express中对中间件有很多分类
// 不关心请求路径和请求方法的中间件
// 也就是说任何请求都会进入这个中间件
// 中间件本身是一个方法,该方法接受三个参数
// Request请求对象
// Response响应对象
// next下一个中间件
// 这里如果中间件中没有next(),那么是不会进入下一个中间件
/* app.use(function (req, res, next) {
console.log('1')
next()
})
app.use(function (req, res, next) {
console.log('2')
next()
}) */
/* app.use(function (req, res, next) {
console.log('first next')
next()
})
*/
// 关心请求路径的中间件:
// 所有以/a开头的,都会请求过来
// 但是此时在下面得的中间件中输出req.url时,它是不包含/a的,处理时会自动去除
/* app.use('/a', function (req, res) {
// console.log('is running at port 3000');
console.log(req.url);
res.send('/a路径请求')
})
app.use(function (req, res, next) {
console.log('second next 第二次,没有匹配的')
next()
}) */
// 以/b开头的会进来
/* app.use('/b', function (req, res) {
// console.log('is running at port 3000');
console.log(req.url);
res.send('/b路径请求')
}) */
// 上面的是应用程序级别的中间件
app.listen(3000, function () {
console.log('app is running at port 3000');
})
其中有几种匹配方式:
// 万能匹配的模式
app.use(function (req, res, next) {
console.log('万能匹配的模式')
next()
})
// 匹配开头的:
// 只有以 /a 开头的才会进来:
app.use('/a', function (req, res) {
// console.log('is running at port 3000');
console.log(req.url);
res.send('/a路径请求')
})
要注意其中传入的参数:
next
一个中间件中传入了next
参数,并且在其中调用了next()
那么在执行完该中间件之后,会调用下一个匹配
的中间件:
app.use(function (req, res, next) {
console.log('first next')
next()
})
app.use('/a', function (req, res) {
// console.log('is running at port 3000');
console.log(req.url);
res.send('/a路径请求')
})
app.use(function (req, res, next) {
console.log('second next 第二次,没有匹配的')
})
在上面中,第一个中间件被调用之后:
- 如果路径是以
/a
开头的,那么会调用第二个中间件,而不会去调用第三个中间件 - 如果路径并不是以
/a
开头的,那么它之后会去调用第三个中间件,而不是去调用第二个
路由器级别中间件
// 除了上面的中间件之外,还有一种最常用的
// 严格匹配请求方法和请求路径的中间件:
// app.get('/')
// app.post('/')
// 下面的是路由器级别的中间件
app.get('/', function (req, res, next) {
console.log('/');
})
app.get('/a', function (req, res, next) {
console.log('/a');
})
上面这些中间件是只有以指定字符串开头的才会进入该中间件