# app.use

在指定路径挂载指定的中间件函数或函数。

# 概要

app.use([path,] callback [, callback...])

在指定路径挂载指定的中间件函数或函数:当请求路径的基数与 path 匹配时执行中间件函数。

# 描述

路由将匹配紧随其路径的任何路径,并带有 "/"。例如:app.use('/apple', ...)将匹配 "/apple"、"/apple/images"、"/apple/images/news" 等。

由于 path默认为 "/",因此对于应用程序的每个请求,都会执行没有路径挂载的中间件。例如,这个中间件函数将为应用程序的每个请求执行:

app.use((req, res, next) => {
  console.log('Time: %d', Date.now())
  next()
})

# 参数

参数 描述 默认
path 调用中间件函数的路径;可以是以下任何一种:表示路径的字符串。 路径模式。 匹配路径的正则表达式模式。 以上任何一种组合的数组。例如,参见 路径示例。 '/'(根路径)
callback 回调函数;可以是:一个中间件函数。 一系列中间件函数(以逗号分隔)。 一组中间件函数。 以上所有的组合。您可以提供多个回调函数,其行为类似于中间件,只是这些回调可以调用 next('route') 以绕过剩余的路由回调。您可以使用此机制对路由施加先决条件,然后如果没有理由继续当前路由,则将控制权传递给后续路由。当回调函数抛出错误或返回被拒绝的 Promise 时,next(err) 将被自动调用。由于 router 和 app 实现了中间件接口,您可以像使用任何其他中间件函数一样使用它们。例如,参见 中间件回调函数示例。

注意

子应用程序将:

  • 不继承具有默认值的设置值。您必须在子应用程序中设置该值。
  • 继承设置的值,没有默认值。

详见 应用程序设置

中间件函数是按顺序执行的,因此中间件包含的顺序很重要。

// this middleware will not allow the request to go beyond it
app.use((req, res, next) => {
  res.send('Hello World')
})

// requests will never reach this route
app.get('/', (req, res) => {
  res.send('Welcome')
})

错误处理中间件

错误处理中间件总是需要四个参数。您必须提供四个参数以将其标识为错误处理中间件函数。即使您不需要使用 next对象,您也必须指定它来维护签名。否则,next对象将被解释为常规中间件,无法处理错误。有关错误处理中间件的详细信息。

以与其他中间件函数相同的方式定义错误处理中间件函数,除了使用四个参数而不是三个参数,特别是使用签名 (err, req, res, next)):

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

# 路径示例

下表提供了一些用于挂载中间件的有效 path值的简单示例。

# 路径

这将匹配以 /abcd 开头的路径:

app.use('/abcd', (req, res, next) => {
  next()
})

# 路径模式

这将匹配以 /abcd 和 /abd 开头的路径:

app.use('/ab(c?)d', (req, res, next) => {
  next()
})

# 正则表达式

这将匹配以 /abc 和 /xyz 开头的路径:

app.use(/\/abc|\/xyz/, (req, res, next) => {
  next()
})

# 数组

这将匹配以 /abcd、/xyza、/lmn 和 /pqr 开头的路径:

app.use(['/abcd', '/xyza', /\/lmn|\/pqr/], (req, res, next) => {
  next()
})

# 中间件回调函数示例

下表提供了可用作 app.use()app.METHOD()app.all()callback参数的中间件函数的一些简单示例。尽管这些示例适用于 app.use(),但它们也适用于 app.use()app.METHOD()app.all()

# 单一中间件

您可以在本地定义和挂载中间件函数。

app.use((req, res, next) => {
  next()
})

路由是有效的中间件。

const router = express.Router()
router.get('/', (req, res, next) => {
  next()
})
app.use(router)

Express 应用程序是有效的中间件。

const subApp = express()
subApp.get('/', (req, res, next) => {
  next()
})
app.use(subApp)

# 系列中间件

您可以在同一挂载路径中指定多个中间件函数。

const r1 = express.Router()
r1.get('/', (req, res, next) => {
  next()
})

const r2 = express.Router()
r2.get('/', (req, res, next) => {
  next()
})

app.use(r1, r2)

# 数组

使用数组对中间件进行逻辑分组。

const r1 = express.Router()
r1.get('/', (req, res, next) => {
  next()
})

const r2 = express.Router()
r2.get('/', (req, res, next) => {
  next()
})

app.use([r1, r2])

# 组合

您可以结合上述所有挂载中间件的方式。

function mw1 (req, res, next) { next() }
function mw2 (req, res, next) { next() }

const r1 = express.Router()
r1.get('/', (req, res, next) => { next() })

const r2 = express.Router()
r2.get('/', (req, res, next) => { next() })

const subApp = express()
subApp.get('/', (req, res, next) => { next() })

app.use(mw1, [mw2, r1, r2], subApp)

以下是在 Express 应用程序中使用 express.static 中间件的一些示例。

从应用程序目录中的 "public" 目录为应用程序提供静态内容:

// GET /style.css etc
app.use(express.static(path.join(__dirname, 'public')))

仅当请求路径以 "/static" 为前缀时,将中间件安装在 "/static" 以提供静态内容:

// GET /static/style.css etc.
app.use('/static', express.static(path.join(__dirname, 'public')))

通过在静态中间件之后加载记录器中间件来禁用静态内容请求的日志记录:

app.use(express.static(path.join(__dirname, 'public')))
app.use(logger())

提供来自多个目录的静态文件,但 "./public" 优先于其他目录:

app.use(express.static(path.join(__dirname, 'public')))
app.use(express.static(path.join(__dirname, 'files')))
app.use(express.static(path.join(__dirname, 'uploads')))
Last Updated: 6/17/2023, 6:57:19 PM