1. 中间件的概念
-
中间件概念的简单理解:把数据从请求到响应分步骤来处理,然后依次有条理的执行,每一个步骤都是一个中间处理环节。
-
中间件的本质就是一个请求处理方法,我们把用户从请求到响应的整个过程分发到多个中间件中去处理,这样做的目的是提高代码的灵活性,动态可扩展的。
-
中间件的书写顺序很重要
-
中间件本身是一个方法,该方法接收三个参数。当每个请求到达服务器时,nodejs会为请求创建一个请求对象(request),该请求对象包含客户端提交上来的数据。同时也会创建一个响应对象(response),响应对象主要负责将服务器的数据响应到客户端。而最后一个参数next是一个方法,因为一个应用中可以使用多个中间件,而要想运行下一个中间件,那么上一个中间件必须运行next()。
- request:请求对象
- response:响应对象
- next:下一个中间件
next 是一个函数,用来调用下一个中间件,但不一定是紧邻的下一个。会向后找第一个匹配的中间件。不匹配就继续往后找。
当一个请求进入一个中间件之后,如果不调用next(),请求就会停留在该中间件里。
2. 在 Express 中,对中间件有几种分类
2.1 应用级别的中间件
万能匹配:不关心请求路径和请求方法的中间件,也就是说任何请求都会进入这个中间件
let express = require('express');
let app = express();
app.use(function (req,res,next) {
console.log('1:收到请求');
next();
})
app.use(function (req,res,next) {
console.log('2:收到请求');
})
2.2 路由中间件
2.2.1 关心请求路径 /xxx
的中间件
// 路径以 /a 开头的请求才会进入
app.use('/a',function (req,res,next) {
console.log('收到请求',req.url);
res.send('end')
})
2.2.2 严格匹配请求方法和请求路径的中间件
//当一个请求是 get 请求,且请求路径以 /a 开头,就会进入该中间件
app.get('/a',function (req,res,next) {
console.log('get /a');
})
//当一个请求是 post 请求,且请求路径以 /login 开头,就会进入该中间件
app.post('/login',function (req,res, next) {
console.log('get /login');
})
2.3 内置中间件
Express具有以下内置中间件功能,官网截图
let express = require('express');
let path = require('path');
let app = express();
//开放资源目录
app.use('/public',express.static(path.join(__dirname,'./public/')));
2.4 第三方中间件
使用第三方中间件为Express应用程序添加功能,需要先安装。
例如,npm install cookie-parser
var express = require('express')
var app = express()
var cookieParser = require('cookie-parser')
app.use(cookieParser())
2.5 自定义中间件
2.5.1 错误处理中间件
配置一个处理404的中间件。如果前面没有任何中间件能够处理,就进入这个中间件。前提是把这个中间件放在最后。
app.use(function (req, res, next) {
res.send('404')
})
2.5.2 全局错误处理中间件
let express = require('express');
let fs = require('fs')
let app = express();
app.get('/test', function (req, res, next) {
//没有这个 cc.txt 文件,读取的时候会报错
fs.readFile('./aa/bb/cc.txt', function (err, data) {
if (err) {
//当调用 next 的时候,如果传递了错误对象参数,则直接往后找到带有四个参数的应用程序级别的中间件
next(err);
}
})
})
//注意四个参数一个都不能少!!!
//全局错误处理中间件,如果前边有一个中间件调用了next(err)方法,并传递了一个错误对象err作为参数,那么就会直接调用这个全局错误处理中间件
app.use(function (err, req, res, next) {
res.status(500).json({
err_code:500,
message:err
})
})
2.6 注意事项
同一个请求所经过的中间件使用的都是同一个请求对象和响应对象。
也就是说对于不同中间件处理的的同一个请求中,req对象是同一个,res对象也是同一个
app.get('/a',function (req,res,next) {
console.log('get /a');
req.foo = 'hello';//在这里给req对象增加了一个属性 foo
next();
})
app.get('/a',function (req,res,next) {
console.log('get /a');
console.log(req.foo);//由于是同一个请求,我们在这里就可以使用req对象的foo
})
3. 资料
https://blog.csdn.net/weixin_33881041/article/details/86128587