express — 中间件
参考:https://www.jianshu.com/p/ffeb2c749cf0
中间件函数参数:
中间件函数可以执行以下任务:
- 执行任何代码。
- 更改请求和响应对象。【不同中间件之间数据交互,就是通过挂载在req上实现的。因为req和res是所有的中间件都共有的对象,这样下一个中间件就可以使用上个中间件提供的数据了】
如,express.json中间件,在解析完请求体后,会向Request对象中添加一个body对象;
Multer 中间件,在解析完请求体后,会向Request对象中添加一个body对象和一个file或files对象(上传多个文件时使用files对象 )。 - 结束请求-响应周期。
- 调用堆栈中的下一个中间件函数。
作用:主要是用来处理请求的,本质就是个函数
中间件本身是一个方法,接收3个参数:request请求对象、response响应对象、next下一个中间件(可选参数,需要调用下一个中间件时使用)
当请求进来,会从第一个中间件开始进行匹配。如果匹配则进入,如果不匹配,则向后依次对比匹配
注意:执行顺序与调用顺序
主要场景:将一个请求的处理过程,分发到多个环节中,目的效率高,便于维护。即每个环节专门干一件事
- request对象:
- response对象:
- res.send 会终结请求,但是后面的代码会继续执行的。http://www.codebaoku.com/question/question-cd-74045.html
res.send(200, { data: 'test data' }); console.log('still here...');
- res.send 会终结请求,但是后面的代码会继续执行的。http://www.codebaoku.com/question/question-cd-74045.html
- next函数:https://www.cnblogs.com/haiguixiansheng/p/10718761.html
如果当前中间件函数没有结束请求(如 res.send就可以结束请求),它必须调用next()
以将控制权传递给下一个中间件函数。否则,请求将被挂起,后面的中间件也不会再执行。
如果我们定义的中间件终结了本次请求,那就不应该再调用next函数,否则就可能会出问题,如下代码:app.get('/a', function(req, res, next) { res.send('sucess'); // 这里已经终结本次请求 next(); }); // catch 404 and forward to error handler app.use(function(req, res, next) { console.log(404); var err = new Error('Not Found'); err.status = 404; next(err); });
中间件函数:
中间件分类:https://www.jianshu.com/p/e7754e3dd89e
-
应用级中间件 (用于权限判断)
app.use((req,res,next)=>{ let data=new Date(); console.log(data) next(); //执行下面的操作,如果不写的话下面就不会执行 })
注意:app.use() 只是 注册了中间件,并没有执行中间件。只有请求进来时,才会根据url 匹配的中间件 从上到下 依次去执行。
-
路由级中间件
如果有两个相同的路由,其中一个没有传值,匹配到第一个之后如果不加next,他就不会在匹配第二个。app.get("/details",(req,res,next)=>{ res.send("执行了"); next(); })
注意:路由级中间件,使用 app.use 和 app.get 的匹配规则有点不一样。比如说app.use("/"),当请求的url是"/hello"或者"/hello/world"都可以匹配到;而app.get("/")就只能匹配url为"/"的。
-
错误处理中间件
作用:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。4个参数缺一不可,只有4个参数都有,express才会把它当 错误处理中间件 。
说明:函数对象是可以获取到函数的 形参数个数 的(function.length),内部机制应该就是 通过 function.length 来 判断 是不是 错误处理中间件的。
实参个数 必须 在调用的时候,函数内部才能知道。
// 错误级别的中间件 app.use((err, req, res, next) => { console.log('发生了错误:' + err.message) res.send('Error! ' + err.message) })
-
内置中间件
app.use(express.static("static"))
-
第三方中间件
const bodyParser=require("body-parser"); app.use(bodyParser.urlencoded({extended:false})); //解析form传过来的值 app.use(bodyParser.json()); //解析传过来的json数据
常用中间件:
- 内置中间件:
- express.static():提供静态资源,如HTML文件,图像等。
- express.json():解析Content-Type为 application/json 格式的请求体
- express.urlencoded():解析Content-Type 为 application/x-www-form-urlencoded 格式的请求体
- express.raw():解析Content-Type为 application/octet-stream 格式的请求体
- express.text(): 解析Content-Type为 text/plain格式 的请求体
- 第三方中间件模块:
express官方也提供了一些第三方中间件,需要单独安装下。express4.xx把一些内置的中间件单独分出来了,保持express的简洁。
- morgan:日志输出
- cors:为客户端提供跨域资源请求
- multer:处理 multipart/form-data 类型的表单 https://blog.csdn.net/KimBing/article/details/126345248 或 https://blog.csdn.net/qq_45859670/article/details/123306590
Multer在解析完请求体后,会向Request对象中添加一个body对象和一个file或files对象(上传多个文件时使用files对象 )。其中,body对象中包含所提交表单中的文本字段(如果有),而file(或files)对象中包含通过表单上传的文件。