五、Express 中间件
中间件是一个函数,它可以访问请求对象(request objeck(req))、响应对象(response object(res)) ,和 Web 应用中处于请求 · 响应循环流程中的中间件;
中间件还有第三个参数 next,用于将此请求传递到下一环节;从本质上来说,一个 Express 应用就是在调用各种中间件。中间件分为以下几种:
应用级中间件(app.use)
路由级中间件(app.get/post...)
错误处理中间件
内置中间件(如我们之前使用的静态资源托管 static 就是内置中间件)
第三方中间件
1. 应用级中间件
应用级中间件绑定到 app对象 使用 app.use() 和 app.METHOD();
新建 1.js 文件进行演示,通过三个中间件来实现访问 /user 路径,记录访问时间、访问日志以及访问次数。
// study_Express/1.js const express = require('express') //require函数引入express包 const app = express() //调用函数 let total = 0; //访问量 //应用级中间件 app.use('/user', (req, res, next) => { //第一个中间件 console.log('访问时间:' + Date.now()) //记录访问时间 next() //进入下一个中间件,不使用next则不会执行下面的中间件 }) app.use('/user', (req, res, next) => { //第二个中间件 console.log('日志:×××访问了/user') //记录访问日志 next() }) app.use('/user', (req, res) => { //第三个中间件 total++; //访问次数增加 console.log('当前访问量:' + total) res.send('返回结果') }) app.listen(3000, () => { //创建监听 console.log('中间件服务器启动成功...') })
启动服务后访问 /user 路径;
此时后台会打印出相关信息,每刷新一次,次数加一;
2. 路由级中间件
新建文件 2.js 进行演示,使用两个中间件打印出1、2。
// study_Express/2.js const express = require('express') //require函数引入express包 const app = express() //调用函数 //路由级中间件 app.get('/luyou', (req, res, next) => { console.log(1) next() }) app.get('/luyou', (req, res) => { console.log(2) }) app.listen(3000, () => { //创建监听 console.log('路由级中间件服务器启动成功...') })
启动服务后访问 /luyou 路径;
后台打印出结果;
此外,路由级中间件中调用 next 时,可以加一个 route 参数 next('route'),意为跳转至下一个路由;
注意区分:
next();跳转至下一个中间件。
next('route');跳转至下一个路由,所谓下一个路由就是通过 get、post 或者其他方式所绑定的路由。
如下面这种写法:
const express = require('express') //require函数引入express包 const app = express() //调用函数 //路由级中间件 app.get('/luyou', (req, res, next) => { //第一个中间件 第一个路由 console.log(1) next('route') //跳转至下一个路由 }, (req, res) => { //第二个中间件 console.log(2) }) app.get('/luyou', (req, res) => { //第三个中间件 第二个路由 console.log(3); res.send('路由级中间件返回结果') }) app.listen(3000, () => { //创建监听 console.log('路由级中间件服务器启动成功...') })
第一个中间件和第二个中间件进行了嵌套,只使用了一个路由,在第一个中间件中使用了 next('route'); 直接跳到了下一路由,所以第二个中间件的结果 2 就不会打印了,如下:
3. 错误处理中间件
错误处理中间件需要4个参数,必须提供四个参数以将其标识为错误处理中间件函数。即使不需要使用 next 对象,也必须指定它。否则,该 next 对象将被解释为常规中间件并且无法处理错误。格式如下:
app.use(function (err, req, res, next) { console.error(err.stack) res.status(500).send('Something broke!') })
4. 第三方中间件 —— body-parser
第三方中间件有很多,在这里我们重点演示参数传递 body-parser,其余第三方中间件用法相同;
首先 npm 安装 body-parser,终端中中使用命令 npm install body-parser --save;
安装成功后会在 package.json 文件中显示;
新建文件 3.js 进行演示,实现简易的登录表单验证功能;
// study_Express/3.js const express = require('express') //require函数引入express包 const app = express() //调用函数 const bodyParser = require('body-parser') //引入body-parser //挂载(启用)内置中间件static,托管静态资源 app.use(express.static('public')) //挂载参数处理中间件(此处解析post表单提交的数据) app.use(bodyParser.urlencoded({ extended: false })) //处理get提交的数据 // app.get('/login', (req, res) => { // let data = req.query; // console.log(data); // res.send('get提交时的数据') // }) //处理post提交的数据 app.post('/login', (req, res) => { let data = req.body; if (data.username == '前端小马' && data.password == '123456') { res.send('登录成功!') } else { res.send('用户名或密码错误!') } }) app.listen(3000, () => { console.log('第三方中间件服务启动...') })
为了展示效果,我们在目录 public 下新建一个 html 文件来制作表单,并托管它;
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>表单</title> <style></style> </head> <body> <form action="http://localhost:3000/login" method="post"> 用户:<input type="text" name="username"><br> 密码:<input type="password" name="password"><br> <input type="submit" value="提交"> </form> </body> </html>
启动服务后访问 /login.html,可以正常验证: