Bootstrap

Express编写中间件

 中间件

注意上面的调用next()。调用此函数会调用应用程序中的下一个中间件函数。该next()函数不是Node.js或Express API的一部分,而是传递给中间件函数的第三个参数。该next()函数可以命名为任何东西,但按照惯例,它总是被命名为“next”。为避免混淆,请始终使用此约定。

中间件函数可以执行以下任务:

  • 执行任何代码。

  • 对请求和响应对象进行更改。

  • 结束请求/响应循环。

  • 调用堆栈中的下一个中间件函数。

如果当前中间件函数没有结束请求/响应循环,那么它必须调用 next(),以将控制权传递给下一个中间件函数。否则,请求将保持挂起状态。

结束请求/响应循环:如果一个中间件函数决定结束请求-响应循环,它可以通过发送一个响应(例如,调用 res.send()res.json())来直接向客户端发送响应。一旦这样做了,请求-响应循环就结束了,后续的中间件将不会被执行。

调用 next():如果中间件函数没有结束请求-响应循环,它必须调用 next() 函数。这样做会将控制权传递给下一个中间件函数,允许请求继续在中间件栈中流动。如果当前中间件是栈中的最后一个,调用 next() 会导致一个错误,因为后面没有更多的中间件来处理请求。

请求挂起状态:如果一个中间件函数既没有结束请求-响应循环,也没有调用 next(),那么请求就会处于挂起状态,既不会发送响应给客户端,也不会继续执行后续的中间件。这通常是一个错误,因为它会导致服务不可用,客户端会一直等待响应。

分类

express可以使用的中间件类型

应用层中间件

使用 app.use()app.METHOD() 函数将应用层中间件绑定到应用程序对象的实例

例子

路由处理程序使您可以为一个路径定义多个路由。以下示例为针对 /user/:id 路径的 GET 请求定义两个路由。第二个路由不会导致任何问题,但是永远都不会被调用,因为第一个路由结束了请求/响应循环。

此示例显示一个中间件子堆栈,用于处理针对 /user/:id 路径的 GET 请求。

app.get('/user/:id', function (req, res, next) {
  console.log('ID:', req.params.id);
  next();
}, function (req, res, next) {
  res.send('User Info');
});

// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', function (req, res, next) {
  res.end(req.params.id);
});

要跳过路由器中间件堆栈中剩余的中间件函数,请调用 next('route') 将控制权传递给下一个路由。

next('route') 仅在使用 app.METHOD() 或 router.METHOD() 函数装入的中间件函数中有效。

此示例显示一个中间件子堆栈,用于处理针对 /user/:id 路径的 GET 请求。

app.get('/user/:id', function (req, res, next) {
  // 当用户id为0的时候,跳到下一个路由处理其
  if (req.params.id == 0) next('route');
  // 其他情况则将控制权给当前中间件栈中的下一个中间件函数
  else next(); //
}, function (req, res, next) {
  // render a regular page
  res.render('regular');
});

// handler for the /user/:id path, which renders a special page
app.get('/user/:id', function (req, res, next) {
  res.render('special');
});

路由器层中间件

路由器层中间件的工作方式与应用层中间件基本相同,差异之处在于它绑定到 express.Router() 的实例。

const router = express.Router();

使用 router.use()router.METHOD() 函数装入路由器层中间件。

错误处理中间件

错误处理中间件始终采用四个自变量。必须提供四个自变量,以将函数标识为错误处理中间件函数。即使无需使用 next 对象,也必须指定该对象以保持特征符的有效性。否则,next 对象将被解释为常规中间件,从而无法处理错误。

错误处理中间件函数的定义方式与其他中间件函数基本相同,差别在于错误处理函数有四个自变量而不是三个,专门具有特征符 (err, req, res, next)

app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

有关错误处理中间件的详细信息,请参阅:错误处理

内置中间件

Express 中唯一内置的中间件函数是 express.static

express.static托管静态资源

express 提供了一个非常好用的函数,叫做express.static(),通过它,我们可以非常方便地创建一个静态资源服务器, 例如,通过如下代码就可以将public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:

app.use(express.static('public'))

现在,你就可以访问public 目录中的所有文件了:

http://localhost:3000/images/bg.jpg

http://localhost:3000/css/style.css

http://localhost:3000/js/login.js

注意:Express 在指定的静态目录中查找文件,并对外提供资源的访问路径。 因此,存放静态文件的目录名不会出现在URL 中。

托管多个静态资源目录

如果要托管多个静态资源目录,请多次调用express.static() 函数:

app.use(express.static('public'))
app. use(express.static('files'))

访问静态资源文件时,express.static() 函数会根据目录的添加顺序查找所需的文件。

第三方中间件

使用第三方中间件向 Express 应用程序添加功能。

安装具有所需功能的 Node.js 模块,然后在应用层或路由器层的应用程序中将其加装入。

以下示例演示如何安装和装入 cookie 解析中间件函数 cookie-parser

$ npm install cookie-parser
const express = require('express');
const app = express();
const cookieParser = require('cookie-parser');

// load the cookie-parsing middleware
app.use(cookieParser());

有关 Express 常用的第三方中间件函数的部分列表,请参阅:第三方中间件

;