一起来认识 Express 中间件,其实也没那么复杂

简介: express是一个基于node.js的web应用框架,它提供了一系列强大的特性,帮助你创建各种web和移动设备应用。express是一个轻量级的包含路由系统的web框架,它没有内置的中间件

express是一个基于node.js的web应用框架,它提供了一系列强大的特性,帮助你创建各种web和移动设备应用。
express是一个轻量级的包含路由系统的web框架,它没有内置的中间件,但是它提供了一系列的中间件。

安装

npm install express --save

快速入门

var express = require('express');
var app = express();

// 注册一个路由
app.get('/', function (req, res) {
   
  res.send('Hello World!');
});

// 启动服务,监听3000端口
app.listen(3000, function () {
   
  console.log('app is listening at port 3000');
});

认识中间件

中间件是一个函数,它可以访问请求对象(request object (req)),响应对象(response object (res)),和web应用中处于请求-响应循环流程中的中间件,一般被命名为next的变量。

中间件的功能包括:

  1. 执行任何代码。
  2. 修改请求和响应对象。
  3. 终结请求-响应循环。
  4. 调用堆栈中的下一个中间件。
  5. 如果当前中间件没有终结请求-响应循环,则必须调用next()方法将控制权交给下一个中间件,否则请求就会挂起。
/* 省略引用 express 的代码 */
app.use(function (req, res, next) {
   
  console.log('Time:', Date.now());
  next();
});

/* 省略路由注册代码和服务启动代码 */

上面的代码中,我们定义了一个中间件,它会在每次请求时打印出当前时间,然后调用next()方法将控制权交给下一个中间件,我们这里只有一个中间件,所以当请求到来时,它会打印出当前时间,然后返回Hello World!

注册中间件时,参数不仅可以是一个函数,还可以是一个包含多个函数的数组,这样就可以注册多个中间件。

function fn(req, res, next) {
   
  console.log('Time:', Date.now());
  next();
}

// 可以是单个函数
app.use(fn);

// 可以是多个参数的函数
app.use(fn, fn);

// 也可以是函数组成的数组
app.use([fn, fn]);

中间件的第一个参数还可以是一个字符串,用来标识一个路径,只有请求的路径匹配了该字符串,才会执行该中间件。

app.use('/user', function (req, res, next) {
   
  console.log(1);
  next();
});

上面的代码中,我们定义了一个中间件,它只有在请求的路径是/user时才会执行,其他的请求地址都不会执行该中间件。

中间件函数的参数

中间件函数的参数分别是request对象response对象next函数err对象,它们的作用分别是:

  1. request对象:表示HTTP请求,包含了请求查询字符串、参数、内容、HTTP头部等属性。
  2. response对象:表示HTTP响应,该对象的方法用于发送HTTP响应。
  3. next函数:是express框架中的核心,表示执行下一个中间件。
  4. err对象:表示错误对象,如果中间件中调用了next()方法并传入了一个参数,则表示发生了错误,参数就是错误对象。

reqresnext这三个参数是必须的,如果定义的中间件函数不需要使用这三个参数,那么就可以省略它们。

err对象是可选的,如果中间件函数中没有发生错误,则可以省略它。

如果中间件函数中发生了错误,则必须调用next()方法,并将错误对象作为参数传入,否则后续的中间件就不会执行了。

如果中间件函数中没有发生错误,则必须调用next()方法,否则后续的中间件就不会执行了。

如果中间件函数中调用了next()方法,并且传入了参数,则后续的中间件就不会执行了。

注意:如果中间件函数中没有调用next()方法,则后续的中间件就不会执行了。

中间件的分类

中间件可以分为应用级中间件和路由级中间件。

应用级中间件

应用级中间件绑定到app对象使用,它的路径是/,即任何路径都可以匹配到。

app.use('/', function (req, res, next) {
   
  console.log('Time:', Date.now());
  next();
});

上面的代码中,我们定义了一个应用级中间件,它会在每次请求时打印出当前时间。

路由级中间件

路由级中间件绑定到express.Router()实例上,它的路径是/,即当前Router实例中的任何路径都可以匹配到。

var express = require('express');
var app = express();

var router = express.Router();

router.use(function (req, res, next) {
   
  console.log('Time:', Date.now());
  next();
});

router.get('/', function (req, res) {
   
  res.send('Hello World!');
});

app.use('/', router);

app.listen(3000, function () {
   
  console.log('app is listening at port 3000');
});

上面的代码中,我们定义了一个路由级中间件,它会在每次请求时打印出当前时间。

路由级中间件的路径是/,即任何路径都可以匹配到,因此,它会在每次请求时打印出当前时间。

也可以为路由级中间件指定一个路径(所有的中间件都可以指定,不仅仅是路由的),这样它就只有在指定的路径才会生效。

var express = require('express');
var app = express();

var router = express.Router();

router.use('/user/:id', function (req, res, next) {
   
  console.log(1);
  next();
});

router.get('/user/:id', function (req, res, next) {
   
  res.send(req.params.id);
});

app.use('/', router);

app.listen(3000, function () {
   
  console.log('app is listening at port 3000');
});

中间件的执行顺序

中间件的执行顺序是按照它们的定义顺序来执行的。

app.use(function (req, res, next) {
   
  console.log(1);
  next();
});

app.use(function (req, res, next) {
   
  console.log(2);
  next();
});

上面的代码中,我们定义了两个中间件,它们的定义顺序是先后的,因此它们的执行顺序也是先后的,所以每次调用接口时,控制台会依次打印出1和2。

中间件的示例

在使用express框架开发Web应用时,没有任何一个开发者离得开中间件,例如json解析中间件cookie解析中间件session中间件静态资源中间件等等。

json解析中间件

express框架内置了一个json解析中间件,可以解析请求体中的json数据。

app.use(express.json());

cookie解析中间件

express框架内置了一个cookie解析中间件,可以解析请求头中的cookie数据。

app.use(express.cookieParser());

session中间件

express框架内置了一个session中间件,可以解析请求头中的session数据。

app.use(express.session());

静态资源中间件

express框架内置了一个静态资源中间件,可以解析请求头中的静态资源数据。

app.use(express.static());

自己实现一个中间件

中间件的本质就是一个函数,只要会写函数,就可以写出一个中间件,现在我们来实现一个用户登录拦截的中间件。

var express = require('express');
var app = express();

app.use(function (req, res, next) {
   
  // 判断白名单地址(不需要登录就可以访问的接口)
  const whiteList = ['/login', '/register'];
  if (whiteList.includes(req.path)) {
   
    next();
    return;
  }

  // 判断用户是否登录
  if (req.session.user) {
   
    next();
    return;
  }

  // 用户未登录,跳转到登录页面
  res.redirect('/login');
});

app.get('/login', function (req, res) {
   
  res.send('登录成功');
});

app.listen(3000, function () {
   
  console.log('app is listening at port 3000');
});

简简单单我们就实现了一个用户登录拦截的中间件,不过功能还是比较简单的,如果系统足够复杂,例如需要对用户的权限进行判断,那么中间件的功能就会变得非常复杂,这时候,我们就需要将中间件拆分成多个小的中间件,然后再组合起来,这样就可以实现中间件的复用。

总结

本文主要介绍了中间件的概念,以及中间件的执行顺序,最后还实现了一个用户登录拦截的中间件。

总体来说中间件的使用还是比较简单的,但是如果要写好一个中间件,还是需要一定的经验的,因为中间件的功能非常复杂,如果不是很熟悉,很容易就会写出一个很复杂的中间件,这样就会导致中间件的可维护性变差,所以在写中间件的时候,一定要注意中间件的可维护性。

参考资料

Express 中间件

目录
相关文章
|
7月前
|
JSON 前端开发 中间件
axios基本使用,express中间件
axios基本使用,express中间件
|
7月前
|
JSON JavaScript 中间件
node.js中Express框架路由,中间件
node.js中Express框架路由,中间件
|
6月前
|
中间件
93 # 实现 express 错误处理中间件
93 # 实现 express 错误处理中间件
27 0
|
3月前
|
JavaScript 前端开发 中间件
Node.js—Express使用、Express 路由 、Express 中间件、托管静态资源、使用 Express 写接口、node.js链接sqlite数据库
Node.js—Express使用、Express 路由 、Express 中间件、托管静态资源、使用 Express 写接口、node.js链接sqlite数据库
117 0
|
4月前
|
Web App开发 JavaScript 前端开发
Express 框架的特点、使用方法以及相关的常用功能和中间件
Express 框架的特点、使用方法以及相关的常用功能和中间件
85 1
|
6月前
|
中间件
92 # express 中的中间件的实现
92 # express 中的中间件的实现
20 0
|
10月前
|
存储 JavaScript 中间件
Express中间件的介绍
Express中间件的介绍
78 0
|
10月前
|
JavaScript NoSQL 中间件
【Node.js实战】一文带你开发博客项目之初识Express(安装Express,处理路由,中间件机制)
【Node.js实战】一文带你开发博客项目之初识Express(安装Express,处理路由,中间件机制)
102 0
|
前端开发 JavaScript 中间件
前端需要去了解的nodejs知识(express中间件)
在上一节中我们简单了解了express的路由,本文主要分析下express的另一个核心功能中间件的使用。路由是express整个框架能有如今广泛使用和发展的基础,那中间件就是其发展的养分。正是express丰富的中间件才节省了我们大量的开发时间。
|
8月前
|
NoSQL Java Redis
阿里Java高级岗中间件二面:GC+IO+JVM+多线程+Redis+数据库+源码
虽然“钱多、事少、离家近”的工作可能离技术人比较远,但是找到一份合适的工作,其实并不像想象中那么难。但是,有些技术人确实是认真努力工作,但在面试时表现出的能力水平却不足以通过面试,或拿到高薪,其实不外乎以下 2 个原因: