5.x API

注意 :这是早期的alpha文档,可能不完整,仍在开发中.

express()

Creates an Express application. The express() function is a top-level function exported by the express module.

const express = require('express')
const app = express()

Methods

express.json([options])

这是Express中的内置中间件功能. 它使用body解析器解析带有JSON负载的传入请求.

返回仅解析JSON并且仅查看Content-Type标头与type选项匹配的请求的中间件. 该解析器接受主体的任何Unicode编码,并支持gzipdeflate编码的自动deflate .

在中间件(即req.body )之后,在request对象上填充一个包含已解析数据的新body对象;如果没有要解析的主体, Content-Type不匹配,则填充一个空对象( {} ).错误发生.

由于req.body的形状基于用户控制的输入,因此该对象中的所有属性和值都是不受信任的,应在信任之前进行验证. 例如, req.body.foo.toString()可能以多种方式失败,例如foo可能不存在或可能不是字符串,而toString可能不是函数,而是字符串或其他用户输入.

下表描述了可选options对象的属性.

Property Description Type Default
inflate 启用或禁用处理压缩的(压缩的)实体; 禁用时,放气的身体将被拒绝. Boolean true
limit 控制最大请求正文大小. 如果这是一个数字,则该值指定字节数;否则为0. 如果是字符串,则将值传递到字节库进行解析. Mixed "100kb"
reviver reviver选项作为第二个参数直接传递给JSON.parse . 您可以在MDN文档中有关JSON.parse的此参数上找到更多信息. Function null
strict 启用或禁用仅接受数组和对象; 禁用时将接受JSON.parse接受的任何内容. Boolean true
type 这用于确定中间件将解析的媒体类型. 此选项可以是字符串,字符串数组或函数. 如果不是函数,则将type选项直接传递到type-is库,并且可以是扩展名(如json ),MIME类型(如application/json )或带通配符的MIME类型(如*/**/json ). 如果是函数,则将type选项称为fn(req)并且如果请求返回真实值,则对该请求进行解析. Mixed "application/json"
verify 如果提供此选项,则称为verify(req, res, buf, encoding) ,其中buf是原始请求主体的Buffer ,而encoding是请求的编码. 抛出错误可以中止解析. Function undefined

express.static(root, [options])

这是Express中的内置中间件功能. 它提供静态文件,并基于serve-static .

注意:为了获得最佳结果,请使用反向代理缓存来提高服务静态资产的性能.

root参数指定用于从其提供静态资产的根目录. 该函数通过将req.url与提供的root目录组合来确定要提供的文件. 当找不到文件时,它不发送404响应,而是调用next()移至下一个中间件,从而可以进行堆栈和回退.

下表描述了options对象的属性. 另请参见下面示例 .

Property Description Type Default
dotfiles 确定如何处理点文件(以点"."开头的文件或目录).

点文件下方.
String “ignore”
etag 启用或禁用etag生成

注意: express.static始终发送弱ETag.
Boolean true
extensions 设置文件扩展名后备:如果未找到文件,请搜索具有指定扩展名的文件并提供找到的第一个文件. 示例: ['html', 'htm'] . Mixed false
fallthrough 让客户端错误作为未处理的请求进入,否则转发客户端错误.

参见下通下方.
Boolean true
immutable Cache-Control响应标头中启用或禁用immutable指令. 如果启用,还应指定maxAge选项以启用缓存. immutable指令将阻止受支持的客户端在maxAge选项maxAge发出条件请求,以检查文件是否已更改. Boolean false
index 发送指定的目录索引文件. 设置为false可禁用目录索引. Mixed “index.html”
lastModified Last-Modified标头设置为OS上文件的最后修改日期. Boolean true
maxAge 设置Cache-Control标头的max-age属性(以毫秒为单位)或以ms格式设置字符串. Number 0
redirect 当路径名是目录时,重定向到结尾的" /". Boolean true
setHeaders 设置HTTP标头以与文件一起使用的功能.

请参阅下面的setHeaders .
Function  

有关更多信息,请参见在Express中提供静态文件 . 和使用中间件-内置中间件 .

dotfiles

此选项的可能值为:

  • "允许"-对点文件没有特殊处理.
  • " deny"-拒绝对点文件的请求,以403响应,然后调用next() .
  • "忽略"-就像点文件不存在一样,以404响应,然后调用next() .

注意 :使用默认值时,它将不会忽略以点开头的目录中的文件.

fallthrough

当此选项为true ,客户端错误(例如错误的请求或对不存在的文件的请求)将导致此中间件仅调用next()来调用堆栈中的下一个中间件. 如果为false,则这些错误(甚至是404错误)将调用next(err) .

将此选项设置为true这样您就可以将多个物理目录映射到同一网址,或用于路由以填充不存在的文件.

如果已将此中间件安装在严格设计为单个文件系统目录的路径上,则使用false ,这可以使404短路以减少开销. 该中间件还将答复所有方法.

setHeaders

对于此选项,指定一个函数来设置自定义响应头. 标头的更改必须同步进行.

该函数的签名是:

fn(res, path, stat)

Arguments:

  • res响应对象 .
  • path ,正在发送的文件路径.
  • stat, the stat object of the file that is being sent.

Example of express.static

这是将express.static中间件函数与精心设计的options对象结合使用的示例:

const options = {
  dotfiles: 'ignore',
  etag: false,
  extensions: ['htm', 'html'],
  index: false,
  maxAge: '1d',
  redirect: false,
  setHeaders: function (res, path, stat) {
    res.set('x-timestamp', Date.now())
  }
}

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

express.Router([options])

创建一个新的路由器对象.

const router = express.Router([options])

可选的options参数指定路由器的行为.

Property Description Default Availability
caseSensitive 启用区分大小写. 默认情况下禁用,将" / Foo"和" / foo"视为相同.  
mergeParams 保留父路由器的req.params值. 如果父项和子项的参数名称冲突,则子项的值优先. false 4.5.0+
strict Enable strict routing. 默认情况下禁用,路由器将" / foo"和" / foo /"视为相同.  

您可以像应用程序一样向router添加中间件和HTTP方法路由(例如getputpost等).

有关更多信息,请参见Router .

express.urlencoded([options])

这是Express中的内置中间件功能. 它使用urlencode的有效载荷解析传入的请求,并且基于body-parser .

返回仅解析urlencoded主体并且仅查看Content-Type标头与type选项匹配的请求的中间件. 该解析器仅接受主体的UTF-8编码,并支持gzipdeflate编码的自动deflate .

在中间件(即req.body )之后,在request对象上填充一个包含已解析数据的新body对象;如果没有要解析的主体, Content-Type不匹配,则填充一个空对象( {} ).错误发生. 该对象将包含键值对,其中值可以是字符串或数组( extendedfalse )或任何类型( extendedtrue ).

由于req.body的形状基于用户控制的输入,因此该对象中的所有属性和值都是不受信任的,应在信任之前进行验证. 例如, req.body.foo.toString()可能以多种方式失败,例如foo可能不存在或可能不是字符串,而toString可能不是函数,而是字符串或其他用户输入.

下表描述了可选options对象的属性.

Property Description Type Default
extended 此选项允许您在使用querystring库(当false )或qs库(当true )解析URL编码的数据之间进行选择. "扩展"语法允许将丰富的对象和数组编码为URL编码格式,从而使URL编码具有类似JSON的体验. 有关更多信息,请参见qs库 . Boolean true
inflate 启用或禁用处理压缩的(压缩的)实体; 禁用时,放气的身体将被拒绝. Boolean true
limit 控制最大请求正文大小. 如果这是一个数字,则该值指定字节数;否则为0. 如果是字符串,则将值传递到字节库进行解析. Mixed "100kb"
parameterLimit 此选项控制URL编码数据中允许的最大参数数量. 如果请求中包含的参数超出该值,则会引发错误. Number 1000
type 这用于确定中间件将解析的媒体类型. 此选项可以是字符串,字符串数组或函数. 如果不是函数,则将type选项直接传递给type-is库,该扩展名可以是扩展名(如urlencoded ),mime类型(如application/x-www-form-urlencoded )或带有a的mime类型.通配符(例如*/x-www-form-urlencoded ). 如果是函数,则将type选项称为fn(req)并且如果请求返回真实值,则对该请求进行解析. Mixed "application/x-www-form-urlencoded"
verify 如果提供此选项,则称为verify(req, res, buf, encoding) ,其中buf是原始请求主体的Buffer ,而encoding是请求的编码. 抛出错误可以中止解析. Function undefined

Application

app对象通常表示Express应用程序. 通过调用Express模块​​导出的顶级express()函数来创建它:

const express = require('express')
const app = express()

app.get('/', function (req, res) {
  res.send('hello world')
})

app.listen(3000)

app对象具有用于

它还具有影响应用程序行为的设置(属性). 有关更多信息,请参阅应用程序设置 .

可以从请求对象响应对象分别将Express应用程序对象称为req.appres.app .

Properties

app.locals

app.locals对象具有作为应用程序内局部变量的属性.

console.dir(app.locals.title)
// => 'My App'

console.dir(app.locals.email)
// => 'me@myapp.com'

设置后, app.locals属性的值将在应用程序的整个生命周期中保持app.locals ,而res.locals属性仅在请求的生命周期内有效.

您可以在应用程序内呈现的模板中访问局部变量. 这对于为模板以及应用程序级数据提供帮助功能很有用. 本地变量可通过req.app.locals在中间件中使用(请参阅req.app

app.locals.title = 'My App'
app.locals.strftime = require('strftime')
app.locals.email = 'me@myapp.com'

app.mountpath

app.mountpath属性包含一个或多个安装了子应用程序的路径模式.

子应用是express一个实例,可用于处理对路线的请求.

const express = require('express')

const app = express() // the main app
const admin = express() // the sub app

admin.get('/', function (req, res) {
  console.log(admin.mountpath) // /admin
  res.send('Admin Homepage')
})

app.use('/admin', admin) // mount the sub app

这是类似的baseUrl的财产req对象,除了req.baseUrl返回,而不是匹配模式匹配的URL路径.

如果将子应用程序安装在多个路径模式上,则app.mountpath返回其安装的模式列表,如以下示例所示.

const admin = express()

admin.get('/', function (req, res) {
  console.log(admin.mountpath) // [ '/adm*n', '/manager' ]
  res.send('Admin Homepage')
})

const secret = express()
secret.get('/', function (req, res) {
  console.log(secret.mountpath) // /secr*t
  res.send('Admin Secret')
})

admin.use('/secr*t', secret) // load the 'secret' router on '/secr*t', on the 'admin' sub app
app.use(['/adm*n', '/manager'], admin) // load the 'admin' router on '/adm*n' and '/manager', on the parent app

app.router

应用程序的内置路由器实例. 这是在第一次访问时延迟创建的.

var express = require('express')
var app = express()
var router = app.router

router.get('/', function (req, res) {
  res.send('hello world')
})

app.listen(3000)

您可以像应用程序一样将中间件和HTTP方法路由添加到router .

有关更多信息,请参见Router .

Events

app.on('mount', callback(parent))

当将其挂载在父应用程序上时,将在子应用程序上触发该mount事件. 父应用程序将传递给回调函数.

NOTE

子应用程序将:

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

有关详细信息,请参阅" 应用程序设置" .

const admin = express()

admin.on('mount', function (parent) {
  console.log('Admin Mounted')
  console.log(parent) // refers to the parent app
})

admin.get('/', function (req, res) {
  res.send('Admin Homepage')
})

app.use('/admin', admin)

Methods

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

此方法类似于标准的app.METHOD()方法,但它匹配所有HTTP动词.

Arguments

Argument Description Default
path 调用中间件功能的路径; 可以是以下任何一个:
  • 表示路径的字符串.
  • 路径模式.
  • 匹配路径的正则表达式模式.
  • 上述任何组合的数组.
有关示例,请参见路径示例 .
'/'(根路径)
callback 回调函数; 可:
  • 中间件功能.
  • 一系列中间件功能(以逗号分隔).
  • 一系列中间件功能.
  • 以上所有的组合.

您可以提供行为类似于中间件的多个回调函数,除了这些回调可以调用next('route')绕过其余的路由回调. 您可以使用此机制在路由上施加先决条件,然后在没有理由继续使用当前路由的情况下将控制权传递给后续路由.

由于路由器应用程序实现了中间件接口,因此您可以像使用任何其他中间件功能一样使用它们.

有关示例,请参见Middleware回调函数示例 .

None

Examples

无论使用GET,POST,PUT,DELETE还是任何其他HTTP请求方法,都会对/secret请求执行以下回调:

app.all('/secret', function (req, res, next) {
  console.log('Accessing the secret section ...')
  next() // pass control to the next handler
})

app.all()方法对于将"全局"逻辑映射为特定的路径前缀或任意匹配很有用. 例如,如果将以下内容放在所有其他路由定义的顶部,则要求从该点开始的所有路由都需要身份验证,并自动加载用户. 请记住,这些回调不必充当端点: loadUser可以执行任务,然后调用next()继续匹配后续路由.

app.all('*', requireAuthentication, loadUser)

或等效的:

app.all('*', requireAuthentication)
app.all('*', loadUser)

另一个示例是列入白名单的"全局"功能. 该示例与上面的示例相似,但是仅限制以" / api"开头的路径:

app.all('/api/*', requireAuthentication)

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

使用指定的回调函数将HTTP DELETE请求路由到指定的路径. 有关更多信息,请参阅路由指南 .

Arguments

Argument Description Default
path 调用中间件功能的路径; 可以是以下任何一个:
  • 表示路径的字符串.
  • 路径模式.
  • 匹配路径的正则表达式模式.
  • 上述任何组合的数组.
有关示例,请参见路径示例 .
'/'(根路径)
callback 回调函数; 可:
  • 中间件功能.
  • 一系列中间件功能(以逗号分隔).
  • 一系列中间件功能.
  • 以上所有的组合.

您可以提供行为类似于中间件的多个回调函数,除了这些回调可以调用next('route')绕过其余的路由回调. 您可以使用此机制在路由上施加先决条件,然后在没有理由继续使用当前路由的情况下将控制权传递给后续路由.

由于路由器应用程序实现了中间件接口,因此您可以像使用任何其他中间件功能一样使用它们.

有关示例,请参见Middleware回调函数示例 .

None

Example

app.delete('/', function (req, res) {
  res.send('DELETE request to homepage')
})

app.disable(name)

将布尔设置name设置为false ,其中name应用程序设置表中的属性之一. 为布尔属性调用app.set('foo', false)与调用app.disable('foo') .

例如:

app.disable('trust proxy')
app.get('trust proxy')
// => false

app.disabled(name)

如果禁用了布尔设置namefalse ),则返回true ,其中name应用程序设置表中的属性之一.

app.disabled('trust proxy')
// => true

app.enable('trust proxy')
app.disabled('trust proxy')
// => false

app.enable(name)

将布尔设置name设置为true ,其中name应用程序设置表中的属性之一. 为布尔属性调用app.set('foo', true)与调用app.enable('foo') .

app.enable('trust proxy')
app.get('trust proxy')
// => true

app.enabled(name)

如果启用了设置nametrue ),则返回true ,其中name应用程序设置表中的属性之一.

app.enabled('trust proxy')
// => false

app.enable('trust proxy')
app.enabled('trust proxy')
// => true

app.engine(ext, callback)

将给定的模板引擎callback注册为ext .

默认情况下,Express将基于文件扩展名require()引擎. 例如,如果尝试呈现" foo.pug"文件,则Express在内部调用以下内容,并在后续调用中缓存require()以提高性能.

app.engine('pug', require('pug').__express)

对于不提供开箱即用.__express引擎,或者如果您希望将另一个扩展名"映射"到模板引擎,请使用此方法.

例如,要将EJS模板引擎映射到" .html"文件:

app.engine('html', require('ejs').renderFile)

在这种情况下,EJS提供的.renderFile()方法具有Express期望的相同签名:( (path, options, callback) ,但请注意,它在内部将此方法别名为ejs.__express因此,如果您使用的是" .ejs"扩展程序,您无需执行任何操作.

某些模板引擎不遵循此约定. consolidate.js库将Node模板引擎映射为遵循此约定,因此它们可与Express无缝协作.

const engines = require('consolidate')
app.engine('haml', engines.haml)
app.engine('html', engines.hogan)

app.get(name)

返回name应用程序设置的值,其中name应用程序设置表中的字符串之一. 例如:

app.get('title')
// => undefined

app.set('title', 'My Site')
app.get('title')
// => "My Site"

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

使用指定的回调函数将HTTP GET请求路由到指定的路径.

Arguments

Argument Description Default
path 调用中间件功能的路径; 可以是以下任何一个:
  • 表示路径的字符串.
  • 路径模式.
  • 匹配路径的正则表达式模式.
  • 上述任何组合的数组.
有关示例,请参见路径示例 .
'/'(根路径)
callback 回调函数; 可:
  • 中间件功能.
  • 一系列中间件功能(以逗号分隔).
  • 一系列中间件功能.
  • 以上所有的组合.

您可以提供行为类似于中间件的多个回调函数,除了这些回调可以调用next('route')绕过其余的路由回调. 您可以使用此机制在路由上施加先决条件,然后在没有理由继续使用当前路由的情况下将控制权传递给后续路由.

由于路由器应用程序实现了中间件接口,因此您可以像使用任何其他中间件功能一样使用它们.

有关示例,请参见Middleware回调函数示例 .

None

有关更多信息,请参阅路由指南 .

Example

app.get('/', function (req, res) {
  res.send('GET request to homepage')
})

app.listen(path, [callback])

启动UNIX套接字,并侦听给定路径上的连接. 此方法与Node的http.Server.listen()相同.

const express = require('express')
const app = express()
app.listen('/tmp/sock')

app.listen([port[, host[, backlog]]][, callback])

绑定并侦听指定主机和端口上的连接. 此方法与Node的http.Server.listen()相同.

如果端口被省略或为0,则操作系统将分配任意未使用的端口,这对于诸如自动化任务(测试等)的情况很有用.

const express = require('express')
const app = express()
app.listen(3000)

express()返回的app实际上是一个JavaScript Function ,旨在将其作为处理请求的回调传递给Node的HTTP服务器. 这使为应用程序的HTTP和HTTPS版本提供相同的代码库变得容易,因为该应用程序不继承自这些代码(它只是一个回调):

const express = require('express')
const https = require('https')
const http = require('http')
const app = express()

http.createServer(app).listen(80)
https.createServer(options, app).listen(443)

app.listen()方法返回http.Server对象,并且(对于HTTP)是用于以下目的的便捷方法:

app.listen = function () {
  var server = http.createServer(this)
  return server.listen.apply(server, arguments)
}

注意:实际上,实际上支持Node的http.Server.listen()方法的所有形式.

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

路由一个HTTP请求,其中METHOD是该请求的HTTP方法,例如小写的GET,PUT,POST等. 因此,实际的方法是app.get()app.post()app.put()等等. 有关完整列表,请参见下面的路由方法 .

Arguments

Argument Description Default
path 调用中间件功能的路径; 可以是以下任何一个:
  • 表示路径的字符串.
  • 路径模式.
  • 匹配路径的正则表达式模式.
  • 上述任何组合的数组.
有关示例,请参见路径示例 .
'/' (root path)
callback 回调函数; 可:
  • 中间件功能.
  • 一系列中间件功能(以逗号分隔).
  • 一系列中间件功能.
  • 以上所有的组合.

您可以提供行为类似于中间件的多个回调函数,除了这些回调可以调用next('route')绕过其余的路由回调. 您可以使用此机制在路由上施加先决条件,然后在没有理由继续使用当前路由的情况下将控制权传递给后续路由.

由于路由器应用程序实现了中间件接口,因此您可以像使用任何其他中间件功能一样使用它们.

有关示例,请参见Middleware回调函数示例 .

None

Routing methods

Express支持以下与相同名称的HTTP方法相对应的路由方法:

  • checkout
  • copy
  • delete
  • get
  • head
  • lock
  • merge
  • mkactivity
  • mkcol
  • move
  • m-search
  • notify
  • options
  • patch
  • post
  • purge
  • put
  • report
  • search
  • subscribe
  • trace
  • unlock
  • unsubscribe

API文档仅对最流行的HTTP方法app.get()app.post()app.put()app.delete()拥有显式条目. 但是,上面列出的其他方法以完全相同的方式工作.

要路由转换为无效JavaScript变量名称的方法,请使用方括号表示法. 例如, app['m-search']('/', function ...

如果未在app.get()之前的路径调用app.head()则除GET方法外,还会自动为HTTP HEAD方法调用app.get()函数.

app.all()方法不是从任何HTTP方法派生的,而是在所有 HTTP请求方法的指定路径处加载中间件. 有关更多信息,请参见app.all .

有关路由的更多信息,请参见路由指南 .

app.param(name, callback)

路由参数添加回调触发器,其中name参数的名称或它们的数组, callback是回调函数. 回调函数的参数依次为请求对象,响应对象,下一个中间件,参数值和参数名称.

如果name是一个数组,则为其声明的每个参数按声明顺序注册callback触发器. 此外,对于除最后一个参数以外的每个已声明参数,在回调内部调用next将调用下一个已声明参数的回调. 对于最后一个参数,对next调用将在当前正在处理的路由的位置调用下一个中间件,就像name只是一个字符串一样.

例如,当:user存在于路径路径中时,您可以映射用户加载逻辑以自动将req.user提供给路径,或对参数输入执行验证.

app.param('user', function (req, res, next, id) {
  // try to get the user details from the User model and attach it to the request object
  User.find(id, function (err, user) {
    if (err) {
      next(err)
    } else if (user) {
      req.user = user
      next()
    } else {
      next(new Error('failed to load user'))
    }
  })
})

参数回调函数对于定义它们的路由器而言是本地的. 它们不会被已安装的应用程序或路由器继承. 因此,仅在app路由上定义的路由参数才会触发在app定义的参数回调.

所有参数回调将在发生该参数的任何路由的任何处理程序之前被调用,并且即使在多个路由中将参数匹配,它们也将在请求-响应周期中仅被调用一次,如以下示例所示.

app.param('id', function (req, res, next, id) {
  console.log('CALLED ONLY ONCE')
  next()
})

app.get('/user/:id', function (req, res, next) {
  console.log('although this matches')
  next()
})

app.get('/user/:id', function (req, res) {
  console.log('and this matches too')
  res.end()
})

GET /user/42 ,打印以下内容:

CALLED ONLY ONCE
although this matches
and this matches too
app.param(['id', 'page'], function (req, res, next, value) {
  console.log('CALLED ONLY ONCE with', value)
  next()
})

app.get('/user/:id/:page', function (req, res, next) {
  console.log('although this matches')
  next()
})

app.get('/user/:id/:page', function (req, res) {
  console.log('and this matches too')
  res.end()
})

GET /user/42/3 ,打印以下内容:

CALLED ONLY ONCE with 42
CALLED ONLY ONCE with 3
although this matches
and this matches too

app.path()

返回应用程序的规范路径(字符串).

const app = express()
const blog = express()
const blogAdmin = express()

app.use('/blog', blog)
blog.use('/admin', blogAdmin)

console.log(app.path()) // ''
console.log(blog.path()) // '/blog'
console.log(blogAdmin.path()) // '/blog/admin'

在已安装应用程序的复杂情况下,此方法的行为会变得非常复杂:通常最好使用req.baseUrl来获取应用程序的规范路径.

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

使用指定的回调函数将HTTP POST请求路由到指定的路径. 有关更多信息,请参阅路由指南 .

Arguments

Argument Description Default
path 调用中间件功能的路径; 可以是以下任何一个:
  • 表示路径的字符串.
  • 路径模式.
  • 匹配路径的正则表达式模式.
  • 上述任何组合的数组.
有关示例,请参见路径示例 .
'/'(根路径)
callback 回调函数; 可:
  • 中间件功能.
  • 一系列中间件功能(以逗号分隔).
  • 一系列中间件功能.
  • 以上所有的组合.

您可以提供行为类似于中间件的多个回调函数,除了这些回调可以调用next('route')绕过其余的路由回调. 您可以使用此机制在路由上施加先决条件,然后在没有理由继续使用当前路由的情况下将控制权传递给后续路由.

由于路由器应用程序实现了中间件接口,因此您可以像使用任何其他中间件功能一样使用它们.

有关示例,请参见Middleware回调函数示例 .

None

Example

app.post('/', function (req, res) {
  res.send('POST request to homepage')
})

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

使用指定的回调函数将HTTP PUT请求路由到指定的路径.

Arguments

Argument Description Default
path 调用中间件功能的路径; 可以是以下任何一个:
  • 表示路径的字符串.
  • 路径模式.
  • 匹配路径的正则表达式模式.
  • 上述任何组合的数组.
有关示例,请参见路径示例 .
'/'(根路径)
callback 回调函数; 可:
  • 中间件功能.
  • 一系列中间件功能(以逗号分隔).
  • 一系列中间件功能.
  • 以上所有的组合.

您可以提供行为类似于中间件的多个回调函数,除了这些回调可以调用next('route')绕过其余的路由回调. 您可以使用此机制在路由上施加先决条件,然后在没有理由继续使用当前路由的情况下将控制权传递给后续路由.

由于路由器应用程序实现了中间件接口,因此您可以像使用任何其他中间件功能一样使用它们.

有关示例,请参见Middleware回调函数示例 .

None

Example

app.put('/', function (req, res) {
  res.send('PUT request to homepage')
})

app.render(view, [locals], callback)

通过callback函数返回视图的呈现HTML. 它接受一个可选参数,该参数是一个包含视图局部变量的对象. 就像res.render()一样 ,除了它不能自行将渲染的视图发送给客户端.

app.render()视为用于生成渲染视图字符串的实用程序函数. 内部res.render()使用app.render()呈现视图.

保留本地变量cache以启用视图缓存. 如果要在开发过程中缓存视图,请将其设置为true ; 默认情况下,生产中启用了视图缓存.

app.render('email', function (err, html) {
  // ...
})

app.render('email', { name: 'Tobi' }, function (err, html) {
  // ...
})

app.route(path)

Returns an instance of a single route, which you can then use to handle HTTP verbs with optional middleware. Use app.route() to avoid duplicate route names (and thus typo errors).

const app = express()

app.route('/events')
  .all(function (req, res, next) {
    // runs for all HTTP verbs first
    // think of it as route specific middleware!
  })
  .get(function (req, res, next) {
    res.json({})
  })
  .post(function (req, res, next) {
    // maybe add a new event...
  })

app.set(name, value)

将设置name分配给value . 您可以存储所需的任何值,但可以使用某些名称来配置服务器的行为. 这些特殊名称在应用程序设置表中列出 .

为布尔属性调用app.set('foo', true)与调用app.enable('foo') . 同样,为布尔属性调用app.set('foo', false)与调用app.disable('foo') .

使用app.get()检索设置的值.

app.set('title', 'My Site')
app.get('title') // "My Site"

Application Settings

下表列出了应用程序设置.

请注意,子应用程序将:

  • 不继承具有默认值的设置的值. 您必须在子应用程序中设置值.
  • 继承没有默认值的设置值; 这些在下表中明确指出.

例外:子应用程序将继承trust proxy的值,即使它具有默认值(出于向后兼容性); 子应用将不会继承生产环境中view cache的值(当NODE_ENV为"生产环境"时).

PropertyTypeDescriptionDefault

case sensitive routing

Boolean

启用区分大小写. 启用后," / Foo"和" / foo"是不同的路由. 禁用时," / Foo"和" / foo"被视为相同.

注意 :子应用程序将继承此设置的值.

不适用(未定义)

env

String 环境模式. 确保在生产环境中设置为"生产"; 请参见生产最佳实践:性能和可靠性 .

process.env.NODE_ENVNODE_ENV环境变量)或"开发"(如果未设置NODE_ENV ).

etag

Varied

设置ETag响应头. 有关可能的值,请参阅etag选项表 .

More about the HTTP ETag header.

weak

jsonp callback name

String 指定默认的JSONP回调名称.

“callback”

json escape

Boolean

res.jsonres.jsonpres.send API启用转义JSON响应. 这将转义字符<>&作为JSON中的Unicode转义序列. 其目的是在客户端嗅探HTML响应时帮助缓解某些类型的持久XSS攻击 .

注意 :子应用程序将继承此设置的值.

不适用(未定义)

json replacer

Varied The 'replacer' argument used by `JSON.stringify`.

注意 :子应用程序将继承此设置的值.

不适用(未定义)

json spaces

Varied JSON.stringify`使用'space'参数 . 通常将其设置为用于缩进经过修饰的JSON的空格数.

注意 :子应用程序将继承此设置的值.

不适用(未定义)

query parser

Varied

通过将值设置为false来禁用查询解析,或者将查询解析器设置为使用"简单"或"扩展"或自定义查询字符串解析功能.

简单的查询解析器基于Node的本机查询解析器querystring .

扩展查询解析器基于qs .

自定义查询字符串解析函数将接收完整的查询字符串,并且必须返回查询键及其值的对象.

"extended"

strict routing

Boolean

启用严格路由. 启用后,路由器会将" / foo"和" / foo /"视为不同. 否则,路由器会将" / foo"和" / foo /"视为相同.

注意 :子应用程序将继承此设置的值.

不适用(未定义)

subdomain offset

Number 要删除以访问子域的主机的点分隔部分的数量. 2

trust proxy

Varied

表示该应用程序位于前端代理之后,并使用X-Forwarded-*标头确定客户端的连接和IP地址. 注意: X-Forwarded-*标头很容易被欺骗,并且检测到的IP地址不可靠.

启用后,Express会尝试确定通过前端代理或一系列代理连接的客户端的IP地址. 然后," req.ips"属性包含客户端连接所经过的IP地址数组. 要启用它,请使用信任代理选项表中描述的值.

" trust proxy"设置是使用proxy-addr包实现的. 有关更多信息,请参见其文档.

注意 :子应用程序继承此设置的值,即使它具有默认值也是如此.

false (disabled)

views

字符串或数组 应用程序视图的目录或目录数组. 如果是数组,则按在数组中出现的顺序查找视图.

process.cwd() + '/views'

view cache

Boolean

启用视图模板编译缓存.

注意 :子应用程序不会在生产环境中继承此设置的值(当" NODE_ENV"为"生产环境"时).

在生产中为true ,否则为undefined.

view engine

String 省略时要使用的默认引擎扩展名.

注意 :子应用程序将继承此设置的值.

不适用(未定义)

x-powered-by

Boolean 启用" X-Powered-By:Express" HTTP标头.

true

Options for `trust proxy` setting

有关更多信息,请阅读代理后的Express .

TypeValue
Boolean

如果为true ,则将客户端的IP地址理解为X-Forwarded-*标头中的最左侧条目.

如果为false ,则该应用程序应被视为直接面向Internet,并且客户端的IP地址是从req.connection.remoteAddress派生的. 这是默认设置.


包含逗号分隔值的字符串
字符串数组

IP地址,子网或IP地址数组和要信任的子网. 预先配置的子网名称为:

  • 回送127.0.0.1/8::1/128
  • linklocal- 169.254.0.0/16 fe80::/10fe80::/10
  • uniquelocal - 10.0.0.0/8172.16.0.0/12192.168.0.0/16fc00::/7

通过以下任意一种方式设置IP地址:

指定一个子网:

app.set('trust proxy', 'loopback')

指定一个子网和一个地址:

app.set('trust proxy', 'loopback, 123.123.123.123')

将多个子网指定为CSV:

app.set('trust proxy', 'loopback, linklocal, uniquelocal')

将多个子网指定为一个数组:

app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal'])

指定后,IP地址或子网将从地址确定过程中排除,并且最接近应用程序服务器的不受信任IP地址被确定为客户端的IP地址.

Number

信任来自前端代理服务器的 跃点作为客户端.

Function

自定义信任实施. 仅当您知道自己在做什么时才使用此功能.

app.set('trust proxy', function (ip) {
  if (ip === '127.0.0.1' || ip === '123.123.123.123') return true // trusted IPs
  else return false
})
Options for `etag` setting

注意 :这些设置仅适用于动态文件,不适用于静态文件. express.static中间件将忽略这些设置.

ETag功能是使用etag包实现的. 有关更多信息,请参见其文档.

TypeValue
Boolean

true启用弱ETag. 这是默认设置.
false完全禁用ETag.

String 如果为" strong",则启用强ETag.
如果为"弱",则启用弱ETag.
Function

Custom ETag function implementation. Use this only if you know what you are doing.

app.set('etag', function (body, encoding) {
  return generateHash(body, encoding) // consider the function is defined
})

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

安装指定的中间件在指定的路径功能或多个功能:当请求的路径的基座匹配执行中间件功能path .

Arguments

Argument Description Default
path 调用中间件功能的路径; 可以是以下任何一个:
  • 表示路径的字符串.
  • 路径模式.
  • 匹配路径的正则表达式模式.
  • 上述任何组合的数组.
有关示例,请参见路径示例 .
'/'(根路径)
callback 回调函数; 可:
  • 中间件功能.
  • 一系列中间件功能(以逗号分隔).
  • 一系列中间件功能.
  • 以上所有的组合.

您可以提供行为类似于中间件的多个回调函数,除了这些回调可以调用next('route')绕过其余的路由回调. 您可以使用此机制在路由上施加先决条件,然后在没有理由继续使用当前路由的情况下将控制权传递给后续路由.

由于路由器应用程序实现了中间件接口,因此您可以像使用任何其他中间件功能一样使用它们.

有关示例,请参见Middleware回调函数示例 .

None

Description

一条路线将匹配紧随其后的任何路径,并带有" / ". 例如: app.use('/apple', ...)将匹配" / apple"," / apple / images"," / apple / images / news",依此类推.

由于path默认为" /",因此对应用程序的每个请求都将执行不带路径安装的中间件.
例如,此中间件功能将针对对应用程序的每个请求执行:

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

NOTE

子应用程序将:

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

有关详细信息,请参阅" 应用程序设置" .

中间件功能是顺序执行的,因此中间件包含的顺序很重要.

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

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

错误处理中间件

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

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

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

Path examples

下表提供了一些用于安装中间件的有效path值的简单示例.

Type Example
Path 这将匹配以/ abcd开头的路径:
 app.use('/abcd', function (req, res, next) { next(); }); 
路径模式 This will match paths starting with `/abcd` and `/abd`:
app.use('/abc?d', function (req, res, next) {
  next();
});
This will match paths starting with `/abcd`, `/abbcd`, `/abbbbbcd`, and so on:
app.use('/ab+cd', function (req, res, next) {
  next();
});
This will match paths starting with `/abcd`, `/abxcd`, `/abFOOcd`, `/abbArcd`, and so on:
app.use('/ab\*cd', function (req, res, next) {
  next();
});
This will match paths starting with `/ad` and `/abcd`:
app.use('/a(bc)?d', function (req, res, next) {
  next();
});
正则表达式 这将匹配以`/ abc`和`/ xyz`开头的路径:
 app.use(/\/abc|\/xyz/, function (req, res, next) { next(); }); 
Array This will match paths starting with `/abcd`, `/xyza`, `/lmn`, and `/pqr`:
app.use(['/abcd', '/xyza', /\/lmn|\/pqr/], function (req, res, next) {
  next();
});

Middleware callback function examples

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

Usage Example
单一中间件 您可以在本地定义和安装中间件功能.
 app.use(function (req, res, next) { next(); }); 
路由器是有效的中间件.
 const router = express.Router(); router.get('/', function (req, res, next) { next(); }); app.use(router); 
Express应用程序是有效的中间件.
 const subApp = express(); subApp.get('/', function (req, res, next) { next(); }); app.use(subApp); 
中间件系列 您可以在同一安装路径中指定多个中间件功能.
 const r1 = express.Router(); r1.get('/', function (req, res, next) { next(); }); const r2 = express.Router(); r2.get('/', function (req, res, next) { next(); }); app.use(r1, r2); 
Array 使用数组对逻辑中间件进行分组. 如果将中间件数组作为第一个或唯一的中间件参数,则必须指定安装路径.
 const r1 = express.Router(); r1.get('/', function (req, res, next) { next(); }); const r2 = express.Router(); r2.get('/', function (req, res, next) { next(); }); app.use('/', [r1, r2]); 
Combination 您可以结合以上所有安装中间件的方式.
 function mw1(req, res, next) { next(); } function mw2(req, res, next) { next(); } const r1 = express.Router(); r1.get('/', function (req, res, next) { next(); }); const r2 = express.Router(); r2.get('/', function (req, res, next) { next(); }); const subApp = express(); subApp.get('/', function (req, res, next) { next(); }); app.use(mw1, [mw2, r1, r2], subApp); 

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

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

// 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')))

Request

req对象代表HTTP请求,并具有请求查询字符串,参数,正文,HTTP标req属性. 在本文档中,按照约定,该对象始终被称为req (HTTP响应为res ),但是其实际名称由您正在使用的回调函数的参数确定.

例如:

app.get('/user/:id', function (req, res) {
  res.send('user ' + req.params.id)
})

但是您也可以拥有:

app.get('/user/:id', function (request, response) {
  response.send('user ' + request.params.id)
})

req对象是Node自己的请求对象的增强版本,并支持所有内置字段和方法 .

Properties

在Express 4中,默认情况下, req.filesreq对象上不再可用. To access uploaded files on the req.files object, use multipart-handling middleware like busboy , multer , formidable , multiparty , connect-multiparty , or pez . 到上访问上传的文件req.files对象,使用多处理中间件像打杂multer强大多方连接多党佩斯 .

req.app

此属性保存对使用中间件的Express应用程序实例的引用.

如果遵循创建仅导出中间件函数并将其在主文件中require()的模块的模式,则中间件可以通过req.app访问Express实例.

例如:

// index.js
app.get('/viewdirectory', require('./mymiddleware.js'))
// mymiddleware.js
module.exports = function (req, res) {
  res.send('The views directory is ' + req.app.get('views'))
}

req.baseUrl

安装路由器实例的URL路径.

req.baseUrl属性类似于app对象的mountpath属性,只是app.mountpath返回匹配的路径模式.

例如:

const greet = express.Router()

greet.get('/jp', function (req, res) {
  console.log(req.baseUrl) // /greet
  res.send('Konichiwa!')
})

app.use('/greet', greet) // load the router on '/greet'

即使您使用路径模式或一组路径模式来加载路由器, baseUrl属性baseUrl返回匹配的字符串,而不是模式. 在以下示例中, greet路由器被加载到两个路径模式上.

app.use(['/gre+t', '/hel{2}o'], greet) // load the router on '/gre+t' and '/hel{2}o'

当对/greet/jp发出请求时, req.baseUrl为" / greet". 当对/hello/jp发出请求时, req.baseUrl为" / hello".

req.body

包含在请求正文中提交的数据的键值对. 默认情况下,它是undefined ,并且在使用body-parsermulter正文分析中间件时填充.

以下示例显示如何使用正文解析中间件填充req.body .

const app = require('express')()
const bodyParser = require('body-parser')
const multer = require('multer') // v1.0.5
const upload = multer() // for parsing multipart/form-data

app.use(bodyParser.json()) // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })) // for parsing application/x-www-form-urlencoded

app.post('/profile', upload.array(), function (req, res, next) {
  console.log(req.body)
  res.json(req.body)
})

req.cookies

使用cookie解析器中间件时,此属性是一个包含请求发送的cookie的对象. 如果请求不包含cookie,则默认为{} .

// Cookie: name=tj
console.dir(req.cookies.name)
// => "tj"

如果cookie已经签名,则必须使用req.signedCookies .

有关更多信息,问题或疑虑,请参阅cookie-parser .

req.fresh

当客户端缓存中的响应仍然"新鲜"时,返回true ,否则返回false ,以指示客户端缓存现在已过时,应发送完整的响应.

当客户端发送Cache-Control: no-cache请求标头以指示端对端重载请求时,此模块将返回false以使这些请求的处理透明.

有关缓存验证工作原理的更多详细信息,请参见HTTP / 1.1缓存规范 .

console.dir(req.fresh)
// => true

req.host

包含派生自Host HTTP标头的Host .

如果trust proxy设置的评估结果不为false ,则此属性将从X-Forwarded-Host标头字段获取值. 此标头可以由客户端或代理设置.

如果请求中有多个X-Forwarded-Host标头,则使用第一个标头的值. 这包括具有逗号分隔值的单个标头,其中使用了第一个值.

// Host: "example.com:3000"
console.dir(req.host)
// => 'example.com:3000'

// Host: "[::1]:3000"
console.dir(req.host)
// => '[::1]:3000'

req.hostname

包含从Host HTTP标头派生的Host名.

如果trust proxy设置的评估结果不为false ,则此属性将从X-Forwarded-Host标头字段获取值. 此标头可以由客户端或代理设置.

如果请求中有多个X-Forwarded-Host标头,则使用第一个标头的值. 这包括具有逗号分隔值的单个标头,其中使用了第一个值.

在Express v4.17.0之前, X-Forwarded-Host不能包含多个值或不能多次出现.

// Host: "example.com:3000"
console.dir(req.hostname)
// => 'example.com'

req.ip

包含请求的远程IP地址.

trust proxy设置的评估结果不为false ,此属性的值将从X-Forwarded-For标头中最左边的条目派生. 此标头可以由客户端或代理设置.

console.dir(req.ip)
// => "127.0.0.1"

req.ips

trust proxy设置的评估结果不为false ,此属性包含X-Forwarded-For请求标头中指定的IP地址数组. 否则,它包含一个空数组. 此标头可以由客户端或代理设置.

例如,如果X-Forwarded-Forclient, proxy1, proxy2 ,则req.ips将是["client", "proxy1", "proxy2"] ,其中proxy2是最远的下游.

req.method

包含与请求的HTTP方法相对应的字符串: GETPOSTPUT等.

req.originalUrl

req.url不是Express的本机属性,它是从Node的http模块继承的.

这个属性很像req.url ; 但是,它保留了原始请求URL,允许您自由重写req.url以进行内部路由. 例如, app.use()的"安装"功能将重写req.url以剥离安装点.

// GET /search?q=something
console.dir(req.originalUrl)
// => "/search?q=something"

在中间件功能中, req.originalUrlreq.baseUrlreq.path的组合,如以下示例所示.

app.use('/admin', function (req, res, next) { // GET 'http://www.example.com/admin/new'
  console.dir(req.originalUrl) // '/admin/new'
  console.dir(req.baseUrl) // '/admin'
  console.dir(req.path) // '/new'
  next()
})

req.params

此属性是一个对象,其中包含映射到命名路由" parameters"的属性. 例如,如果您具有路由/user/:name ,则" name"属性可以作为req.params.name . 该对象默认为{} .

// GET /user/tj
console.dir(req.params.name)
// => "tj"

当使用正则表达式进行路由定义时,使用req.params[n]在数组中提供捕获组,其中n是第n 捕获组. 此规则适用于具有字符串路由(例如/file/*未命名通配符匹配:

// GET /file/javascripts/jquery.js
console.dir(req.params[0])
// => "javascripts/jquery.js"

如果您需要对req.params的键进行更改,请使用app.param处理程序. 更改仅适用于已在路径中定义的参数 .

在中间件或路由处理程序中对req.params对象所做的任何更改都将被重置.

注意:Express会自动解码req.params的值(使用decodeURIComponent ).

req.path

包含请求URL的路径部分.

// example.com/users?sort=desc
console.dir(req.path)
// => "/users"

从中间件调用时,安装点不包括在req.path . 有关更多详细信息,请参见app.use() .

req.protocol

包含请求协议字符串: http或(对于TLS请求) https .

trust proxy设置的评估结果不为false ,此属性将使用X-Forwarded-Proto标头字段的值(如果存在). 此标头可以由客户端或代理设置.

console.dir(req.protocol)
// => "http"

req.query

This property is an object containing a property for each query string parameter in the route. When query parser is set to disabled, it is an empty object {}, otherwise it is the result of the configured query parser.

由于req.query的形状基于用户控制的输入,因此该对象中的所有属性和值都不可信,应在可信之前进行验证. 例如, req.query.foo.toString()可能以多种方式失败,例如foo可能不存在或可能不是字符串,并且toString可能不是函数,而是字符串或其他用户输入.

// GET /search?q=tobi+ferret
console.dir(req.query.q)
// => "tobi ferret"

// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
console.dir(req.query.order)
// => "desc"

console.dir(req.query.shoe.color)
// => "blue"

console.dir(req.query.shoe.type)
// => "converse"

// GET /shoes?color[]=blue&color[]=black&color[]=red
console.dir(req.query.color)
// => [blue, black, red]

req.route

包含当前匹配的路由,一个字符串. 例如:

app.get('/user/:id?', function userIdHandler (req, res) {
  console.log(req.route)
  res.send('GET')
})

上一片段的示例输出:

{ path: '/user/:id?',
  stack:
   [ { handle: [Function: userIdHandler],
       name: 'userIdHandler',
       params: undefined,
       path: undefined,
       keys: [],
       regexp: /^\/?$/i,
       method: 'get' } ],
  methods: { get: true } }

req.secure

一个布尔属性,如果建立TLS连接,则为true. 等效于以下内容:

req.protocol === 'https'

req.signedCookies

使用cookie解析器中间件时,此属性包含请求发送的已签名的cookie,未签名且可以使用. 已签名的cookie位于另一个对象中,以显示开发人员的意图. 否则,可能会对req.cookie值(很容易欺骗)进行恶意攻击. 请注意,对cookie签名不会使其"隐藏"或加密. 但只是防止篡改(因为用于签名的秘密是私有的).

如果没有发送签名的cookie,则该属性默认为{} .

// Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3
console.dir(req.signedCookies.user)
// => "tobi"

有关更多信息,问题或疑虑,请参阅cookie-parser .

req.stale

指示请求是否为"过时",是否与req.fresh相反. 有关更多信息,请参见req.fresh .

console.dir(req.stale)
// => true

req.subdomains

请求域名中的子域数组.

// Host: "tobi.ferrets.example.com"
console.dir(req.subdomains)
// => ["ferrets", "tobi"]

应用程序属性subdomain offset (默认为2)用于确定子域段的开头. 要更改此行为,请使用app.set更改其值.

req.xhr

一个布尔型属性,如果请求的X-Requested-With标头字段为" XMLHttpRequest",则为true ,指示该请求是由客户端库(如jQuery)发出的.

console.dir(req.xhr)
// => true

Methods

req.accepts(types)

根据请求的" Accept HTTP标头"字段检查指定的内容类型是否可接受. 该方法返回最佳匹配,或者如果指定的内容类型都不可接受,则返回false (在这种情况下,应用程序应使用406 "Not Acceptable"响应).

type值可以是单个MIME类型字符串(例如" application / json"),扩展名(例如" json"),逗号分隔列表或数组. 对于列表或数组,该方法返回最佳匹配项(如果有).

// Accept: text/html
req.accepts('html')
// => "html"

// Accept: text/*, application/json
req.accepts('html')
// => "html"
req.accepts('text/html')
// => "text/html"
req.accepts(['json', 'text'])
// => "json"
req.accepts('application/json')
// => "application/json"

// Accept: text/*, application/json
req.accepts('image/png')
req.accepts('png')
// => false

// Accept: text/*;q=.5, application/json
req.accepts(['html', 'json'])
// => "json"

有关更多信息,或者您有任何问题或疑虑,请参见接受 .

req.acceptsCharsets(charset [, ...])

根据请求的Accept-Charset HTTP标头字段,返回指定字符集的第一个接受的字符集. 如果不接受任何指定的字符集,则返回false .

有关更多信息,或者您有任何问题或疑虑,请参见接受 .

req.acceptsEncodings(encoding [, ...])

根据请求的Accept-Encoding HTTP标头字段,返回指定编码的第一个接受的编码. 如果不接受任何指定的编码,则返回false .

有关更多信息,或者您有任何问题或疑虑,请参见接受 .

req.acceptsLanguages(lang [, ...])

根据请求的Accept-Language HTTP标头字段,返回指定语言的第一种接受的语言. 如果不接受任何指定的语言,则返回false .

有关更多信息,或者您有任何问题或疑虑,请参见接受 .

req.get(field)

返回指定的HTTP请求标头字段(不区分大小写的匹配). ReferrerReferer字段是可互换的.

req.get('Content-Type')
// => "text/plain"

req.get('content-type')
// => "text/plain"

req.get('Something')
// => undefined

req.header(field)req.header(field) .

req.is(type)

如果传入请求的" Content-Type" HTTP标头字段与type参数指定的MIME类型匹配,则返回匹配的内容类型. 如果请求没有正文,则返回null . 否则返回false .

// With Content-Type: text/html; charset=utf-8
req.is('html') // => 'html'
req.is('text/html') // => 'text/html'
req.is('text/*') // => 'text/*'

// When Content-Type is application/json
req.is('json') // => 'json'
req.is('application/json') // => 'application/json'
req.is('application/*') // => 'application/*'

req.is('html')
// => false

有关更多信息,或者如果您有任何问题或疑虑,请参阅type-is .

req.range(size[, options])

Range标头解析器.

size参数是资源的最大大小.

options参数是一个可以具有以下属性的对象.

Property Type Description
combine Boolean 指定是否应合并重叠范围和相邻范围,默认为false . 如果为true ,则将合并范围并返回它们,就像在标头中以这种方式指定它们一样.

将返回范围数组或负数,指示错误解析.

  • -2表示格式错误的标题字符串
  • -1表示范围无法满足
// parse header from request
const range = req.range(1000)

// the type of the range
if (range.type === 'bytes') {
  // the ranges
  range.forEach(function (r) {
    // do something with r.start and r.end
  })
}

Response

res对象表示Express应用收到HTTP请求时发送的HTTP响应.

在本文档中,按照约定,该对象始终被称为res (并且HTTP请求为req ),但是其实际名称由您正在使用的回调函数的参数确定.

例如:

app.get('/user/:id', function (req, res) {
  res.send('user ' + req.params.id)
})

但是您也可以拥有:

app.get('/user/:id', function (request, response) {
  response.send('user ' + request.params.id)
})

The res object is an enhanced version of Node’s own response object and supports all built-in fields and methods.

Properties

res.app

此属性保存对使用中间件的Express应用程序实例的引用.

res.app与请求对象中的req.app属性相同.

res.headersSent

布尔值属性,指示应用程序是否为响应发送了HTTP标头.

app.get('/', function (req, res) {
  console.log(res.headersSent) // false
  res.send('OK')
  console.log(res.headersSent) // true
})

res.locals

一个对象,该对象包含范围为请求的响应局部变量,因此仅可用于在该请求/响应周期(如果有)中呈现的视图. 否则,此属性与app.locals相同.

此属性对于公开请求级别的信息很有用,例如请求路径名,经过身份验证的用户,用户设置等.

app.use(function (req, res, next) {
  res.locals.user = req.user
  res.locals.authenticated = !req.user.anonymous
  next()
})

Methods

res.append(field [, value])

Express v4.11.0 +支持res.append()

将指定的value附加到HTTP响应标头field . 如果尚未设置标题,它将创建具有指定值的标题. value参数可以是字符串或数组.

注:调用res.set()res.append()将重置预先设定的头值.

res.append('Link', ['<http://localhost/>', '<http://localhost:3000/>'])
res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly')
res.append('Warning', '199 Miscellaneous warning')

res.attachment([filename])

将HTTP响应的Content-Disposition标头字段设置为" attachment". 如果提供了filename ,则它通过res.type()基于扩展名设置Content-Type,并设置Content-Disposition " filename ="参数.

res.attachment()
// Content-Disposition: attachment

res.attachment('path/to/logo.png')
// Content-Disposition: attachment; filename="logo.png"
// Content-Type: image/png

res.cookie(name, value [, options])

将cookie name设置为value . value参数可以是字符串或转换为JSON的对象.

options参数是一个可以具有以下属性的对象.

Property Type Description
domain String Cookie的域名. 默认为应用程序的域名.
encode Function 用于cookie值编码的同步函数. 默认为encodeURIComponent .
expires Date Cookie在GMT中的到期日期. 如果未指定或设置为0,则创建会话cookie.
httpOnly Boolean 将Cookie标记为只能由Web服务器访问.
maxAge Number 方便的选项,用于设置相对于当前时间的到期时间(以毫秒为单位).
path String Cookie的路径. 默认为" /".
secure Boolean 将cookie标记为仅与HTTPS一起使用.
signed Boolean 指示是否应该对cookie进行签名.
sameSite 布尔值或字符串 " SameSite" Set-Cookie属性的值. 有关更多信息, 请参见https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1 .

res.cookie()所做的所有操作res.cookie()使用提供的选项设置HTTP Set-Cookie标头. 未指定的任何选项默认为RFC 6265中规定的值.

例如:

res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true })
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true })

encode选项允许您选择使用cookie值编码的功能. 不支持异步功能.

用例示例:您需要为组织中的另一个站点设置域范围的cookie. 此其他站点(不受您的管理控制)不使用URI编码的cookie值.

// Default encoding
res.cookie('some_cross_domain_cookie', 'http://mysubdomain.example.com', { domain: 'example.com' })
// Result: 'some_cross_domain_cookie=http%3A%2F%2Fmysubdomain.example.com; Domain=example.com; Path=/'

// Custom encoding
res.cookie('some_cross_domain_cookie', 'http://mysubdomain.example.com', { domain: 'example.com', encode: String })
// Result: 'some_cross_domain_cookie=http://mysubdomain.example.com; Domain=example.com; Path=/;'

maxAge选项是用于设置相对于当前时间(以毫秒为单位)的"过期时间"的便捷选项. 以下等效于上面的第二个示例.

res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })

您可以传递一个对象作为value参数. 然后将其序列化为JSON,并由bodyParser()中间件进行解析.

res.cookie('cart', { items: [1, 2, 3] })
res.cookie('cart', { items: [1, 2, 3] }, { maxAge: 900000 })

使用cookie解析器中间件时,此方法还支持签名的cookie. 只需将设置为truesigned选项包括在内即可. 然后res.cookie()将使用传递给cookieParser(secret)对值进行签名.

res.cookie('name', 'tobi', { signed: true })

稍后,您可以通过req.signedCookies对象访问此值.

res.clearCookie(name [, options])

清除由name指定的cookie. 有关options对象的详细信息,请参见res.cookie() .

如果给定的options与给res.cookie()相同的options 不包括expiresmaxAge ,则Web浏览器和其他兼容的客户端只会清除cookie.

res.cookie('name', 'tobi', { path: '/admin' })
res.clearCookie('name', { path: '/admin' })

res.download(path [, filename] [, options] [, fn])

The optional options argument is supported by Express v4.16.0 onwards.

path中以"附件"形式传输文件. 通常,浏览器会提示用户下载. 默认情况下, Content-Disposition标头的" filename ="参数是path (通常显示在浏览器对话框中). 使用filename参数覆盖此默认值.

当发生错误或传输完成时,该方法将调用可选的回调函数fn . 此方法使用res.sendFile()传输文件.

可选的options参数传递给基础的res.sendFile()调用,并采用完全相同的参数.

res.download('/report-12345.pdf')

res.download('/report-12345.pdf', 'report.pdf')

res.download('/report-12345.pdf', 'report.pdf', function (err) {
  if (err) {
    // Handle error, but keep in mind the response may be partially-sent
    // so check res.headersSent
  } else {
    // decrement a download credit, etc.
  }
})

res.end([data] [, encoding])

结束响应过程. 该方法实际上来自Node核心,特别是http.ServerResponseresponse.end()方法 .

用于快速结束响应,而无需任何数据. 如果需要用数据响应,请使用诸如res.send()res.json()之类的方法 .

res.end()
res.status(404).end()

res.format(object)

如果存在,则对请求对象上的Accept HTTP标头执行内容协商. 它使用req.accepts()根据质量值排序的可接受类型为请求选择处理程序. 如果未指定头,则调用第一个回调. 如果找不到匹配项,则服务器以406"不可接受"响应,或调用default回调.

The Content-Type response header is set when a callback is selected. However, you may alter this within the callback using methods such as res.set() or res.type().

下面的示例在Accept标头字段设置为" application / json"或" * / json"(但是如果为" * / *",则响应为{ "message": "hey" }时,响应为"嘿").

res.format({
  'text/plain': function () {
    res.send('hey')
  },

  'text/html': function () {
    res.send('<p>hey</p>')
  },

  'application/json': function () {
    res.send({ message: 'hey' })
  },

  default: function () {
    // log the request and respond with 406
    res.status(406).send('Not Acceptable')
  }
})

除了规范化的MIME类型之外,您还可以使用映射到这些类型的扩展名来实现稍微冗长的实现:

res.format({
  text: function () {
    res.send('hey')
  },

  html: function () {
    res.send('<p>hey</p>')
  },

  json: function () {
    res.send({ message: 'hey' })
  }
})

res.get(field)

返回由field指定的HTTP响应标头. 匹配不区分大小写.

res.get('Content-Type')
// => "text/plain"

res.json([body])

发送JSON响应. 此方法发送响应(具有正确的内容类型),该响应是使用JSON.stringify()转换为JSON字符串的参数.

该参数可以是任何JSON类型,包括对象,数组,字符串,布尔值,数字或null,并且您还可以使用它将其他值转换为JSON.

res.json(null)
res.json({ user: 'tobi' })
res.status(500).json({ error: 'message' })

res.jsonp([body])

发送带有JSONP支持的JSON响应. 此方法与res.json()相同,除了它选择加入JSONP回调支持.

res.jsonp(null)
// => callback(null)

res.jsonp({ user: 'tobi' })
// => callback({ "user": "tobi" })

res.status(500).jsonp({ error: 'message' })
// => callback({ "error": "message" })

默认情况下,JSONP回调名称就是callback . 使用jsonp回调名称设置覆盖此设置.

以下是使用相同代码的JSONP响应的一些示例:

// ?callback=foo
res.jsonp({ user: 'tobi' })
// => foo({ "user": "tobi" })

app.set('jsonp callback name', 'cb')

// ?cb=foo
res.status(500).jsonp({ error: 'message' })
// => foo({ "error": "message" })

连接作为参数属性提供的links ,以填充响应的" Link HTTP"头字段.

例如,以下调用:

res.links({
  next: 'http://api.example.com/users?page=2',
  last: 'http://api.example.com/users?page=5'
})

产生以下结果:

Link: <http://api.example.com/users?page=2>; rel="next",
      <http://api.example.com/users?page=5>; rel="last"

res.location(path)

将响应Location HTTP标头设置为指定的path参数.

res.location('/foo/bar')
res.location('http://example.com')
res.location('back')

path值" back"具有特殊含义,它引用请求的Referer标头中指定的URL. 如果未指定Referer标头,则它引用" /".

对URL进行编码后,如果尚未进行编码,则Express会在不进行任何验证的情况下将指定的URL传递给Location标头中的浏览器.

浏览器负责从当前URL或引用URL以及Location标头中指定的URL派生预期URL; 并相应地重定向用户.

res.redirect([status,] path)

重定向到从具有指定status的指定path派生的URL,该status为与HTTP状态代码相对应的正整数. 如果未指定,则status默认为" 302"已找到".

res.redirect('/foo/bar')
res.redirect('http://example.com')
res.redirect(301, 'http://example.com')
res.redirect('../login')

重定向可以是用于重定向到其他站点的标准URL:

res.redirect('http://google.com')

重定向可以相对于主机名的根. 例如,如果应用程序位于http://example.com/admin/post/new ,则以下内容将重定向到URL http://example.com/admin

res.redirect('/admin')

重定向可以相对于当前URL. 例如,从http://example.com/blog/admin/ (请注意后跟斜杠)中,以下内容将重定向到URL http://example.com/blog/admin/post/new .

res.redirect('post/new')

http://example.com/blog/admin重定向到post/new (没有斜杠),将重定向到http://example.com/blog/post/new .

如果您发现上述行为令人困惑,请将路径段视为目录(带有斜杠)和文件,这将变得有意义.

相对路径重定向也是可能的. 如果您使用的是http://example.com/admin/post/new ,则以下内容将重定向到http://example.com/admin/post

res.redirect('..')

back重定向将请求重定向回引用者 ,缺少引用者时默认为/ .

res.redirect('back')

res.render(view [, locals] [, callback])

渲染view ,并将渲染的HTML字符串发送到客户端. 可选参数:

  • locals ,一个对象,其属性定义视图的局部变量.
  • callback ,一个回调函数. 如果提供了此方法,则该方法将返回可能的错误和呈现的字符串,但不会执行自动响应. 发生错误时,该方法next(err)内部调用next(err) .

view参数是一个字符串,它是要呈现的视图文件的文件路径. 这可以是绝对路径,也可以是相对于views设置的路径. 如果路径不包含文件扩展名,则view engine设置将确定文件扩展名. 如果路径中确实包含文件扩展名,则Express将为指定的模板引擎加载模块(通过require() ),并使用加载的模块的__express函数对其进行呈现.

有关更多信息,请参阅将模板引擎与Express结合使用 .

注意: view参数执行文件系统操作,例如从磁盘读取文件并评估Node.js模块,因此出于安全原因,不应包含最终用户的输入.

局部变量cache启用视图缓存. 将其设置为true ,以在开发期间缓存视图; 默认情况下,生产中启用了视图缓存.

// send the rendered view to the client
res.render('index')

// if a callback is specified, the rendered HTML string has to be sent explicitly
res.render('index', function (err, html) {
  res.send(html)
})

// pass a local variable to the view
res.render('user', { name: 'Tobi' }, function (err, html) {
  // ...
})

res.send([body])

发送HTTP响应.

body参数可以是Buffer对象, String ,对象或Array . 例如:

res.send(Buffer.from('whoop'))
res.send({ some: 'json' })
res.send('<p>some html</p>')
res.status(404).send('Sorry, we cannot find that!')
res.status(500).send({ error: 'something blew up' })

此方法对简单的非流式响应执行许多有用的任务:例如,它自动分配Content-Length HTTP响应标头字段(除非先前定义),并提供自动的HEAD和HTTP缓存新鲜度支持.

当参数是Buffer对象时,该方法将Content-Type响应标头字段设置为" application / octet-stream",除非先前定义如下:

res.set('Content-Type', 'text/html')
res.send(Buffer.from('<p>some html</p>'))

当参数为String ,该方法将Content-Type为" text / html":

res.send('<p>some html</p>')

当参数是ArrayObject ,Express会以JSON表示形式进行响应:

res.send({ user: 'tobi' })
res.send([1, 2, 3])

res.sendFile(path [, options] [, fn])

Express v4.8.0及更高版本支持res.sendFile() .

在给定path传输文件. 根据文件名的扩展名设置Content-Type响应HTTP标头字段. 除非在options对象中设置了root选项,否则path必须是文件的绝对路径.

该API提供对正在运行的文件系统上的数据的访问. 确保(a)如果path参数包含用户输入,则将path参数构造为绝对路径的方法是安全的;或者(b)将root选项设置为root的绝对路径,以在其中包含访问权限.

提供root选项时, path参数允许为相对路径,包括.. Express将验证所提供的相对路径path将给予内解决root的选择.

下表提供了options参数的详细信息.

Property Description Default Availability
maxAge 设置Cache-Control标头的max-age属性(以毫秒为单位)或以ms格式设置的字符串 0  
root 相对文件名的根目录.    
lastModified Last-Modified标头设置为OS上文件的最后修改日期. 设置为false将其禁用. Enabled 4.9.0+
headers 包含要与文件一起使用的HTTP标头的对象.    
dotfiles 用于提供点文件的选项. 可能的值为"允许","拒绝","忽略". “ignore”  
acceptRanges 启用或禁用接受远程请求. true 4.14+
cacheControl 启用或禁用设置Cache-Control响应标头. true 4.14+
immutable Enable or disable the immutable directive in the Cache-Control response header. If enabled, the maxAge option should also be specified to enable caching. The immutable directive will prevent supported clients from making conditional requests during the life of the maxAge option to check if the file has changed. false 4.16+

传输完成或发生错误时,该方法将调用回调函数fn(err) . 如果指定了回调函数并且发生错误,则回调函数必须通过结束请求-响应周期或将控制权传递到下一个路由来显式处理响应过程.

这是使用res.sendFile及其所有参数的示例.

app.get('/file/:name', function (req, res, next) {
  const options = {
    root: path.join(__dirname, 'public'),
    dotfiles: 'deny',
    headers: {
      'x-timestamp': Date.now(),
      'x-sent': true
    }
  }

  const fileName = req.params.name
  res.sendFile(fileName, options, function (err) {
    if (err) {
      next(err)
    } else {
      console.log('Sent:', fileName)
    }
  })
})

以下示例说明了如何使用res.sendFile为服务文件提供细粒度的支持:

app.get('/user/:uid/photos/:file', function (req, res) {
  const uid = req.params.uid
  const file = req.params.file

  req.user.mayViewFilesFrom(uid, function (yes) {
    if (yes) {
      res.sendFile('/uploads/' + uid + '/' + file)
    } else {
      res.status(403).send("Sorry! You can't see that.")
    }
  })
})

For more information, or if you have issues or concerns, see send.

res.sendStatus(statusCode)

将响应HTTP状态代码设置为statusCode并将其字符串表示形式发送为响应主体.

res.sendStatus(200) // equivalent to res.status(200).send('OK')
res.sendStatus(403) // equivalent to res.status(403).send('Forbidden')
res.sendStatus(404) // equivalent to res.status(404).send('Not Found')
res.sendStatus(500) // equivalent to res.status(500).send('Internal Server Error')

如果指定了不受支持的状态代码,则HTTP状态仍设置为statusCode并且该代码的字符串版本作为响应正文发送.

res.statusCode设置为无效的HTTP状态代码(超出100599的范围)时,将抛出某些版本的res.statusCode 请查阅HTTP服务器文档以获取所使用的Node.js版本.

res.sendStatus(9999) // equivalent to res.status(9999).send('9999')

More about HTTP Status Codes

res.set(field [, value])

将响应的HTTP标头fieldvalue . 要一次设置多个字段,请传递一个对象作为参数.

res.set('Content-Type', 'text/plain')

res.set({
  'Content-Type': 'text/plain',
  'Content-Length': '123',
  ETag: '12345'
})

res.header(field [, value])res.header(field [, value]) .

res.status(code)

设置响应的HTTP状态. 它是Node的response.statusCode的可链接别名.

res.status(403).end()
res.status(400).send('Bad Request')
res.status(404).sendFile('/absolute/path/to/404.png')

res.type(type)

Content-Type HTTP标头设置为mime.lookup()为指定type确定的MIME type . 如果type包含" /"字符,则它将Content-Typetype .

res.type('.html') // => 'text/html'
res.type('html') // => 'text/html'
res.type('json') // => 'application/json'
res.type('application/json') // => 'application/json'
res.type('png') // => image/png:

res.vary(field)

如果该字段尚未存在,则将其添加到Vary响应头中.

res.vary('User-Agent').render('docs')

Router

router对象是中间件和路由的隔离实例. 您可以将其视为"微型应用程序",仅能执行中间件和路由功能. 每个Express应用程序都有一个内置的应用路由器.

路由器的行为类似于中间件本身,因此您可以将其用作app.use()的参数或用作另一台路由器的use()方法的参数.

顶级express对象具有一个Router()方法,该方法创建一个新的router对象.

创建路由器对象post ,就可以像应用程序一样向其添加中间件和HTTP方法路由(例如getputpost等). 例如:

// invoked for any requests passed to this router
router.use(function (req, res, next) {
  // .. some logic here .. like any other middleware
  next()
})

// will handle any request that ends in /events
// depends on where the router is "use()'d"
router.get('/events', function (req, res, next) {
  // ..
})

然后,您可以将路由器用于特定的根URL,以这种方式将路由分为文件或什至是微型应用程序.

// only requests to /calendar/* will be sent to our "router"
app.use('/calendar', router)

Methods

router.all(path, [callback, ...] callback)

此方法类似于router.METHOD()方法,除了它与所有HTTP方法(动词)匹配之外.

该方法对于映射"全局"逻辑以获取特定的路径前缀或任意匹配项非常有用. 例如,如果将以下路由放在所有其他路由定义的顶部,则将要求从该点开始的所有路由都需要身份验证,并自动加载用户. 请记住,这些回调不必充当端点. loadUser可以执行任务,然后调用next()继续匹配后续路由.

router.all('*', requireAuthentication, loadUser)

或等效的:

router.all('*', requireAuthentication)
router.all('*', loadUser)

另一个例子是列入白名单的"全局"功能. 这里的示例与以前非常相似,但是只限制了以" / api"为前缀的路径:

router.all('/api/*', requireAuthentication)

router.METHOD(path, [callback, ...] callback)

router.METHOD()方法提供Express中的路由功能,其中METHOD是HTTP方法之一,例如小写的GET,PUT,POST等. 因此,实际的方法是router.get()router.post()router.put()等.

如果未在router.get()之前的路径中调用router.head()则除GET方法外,还会自动为HTTP HEAD方法调用router.get()函数.

您可以提供多个回调,所有回调都被同等对待,并且其行为与中间件相同,不同之处在于这些回调可以调用next('route')绕过其余的路由回调. 您可以使用此机制在路由上执行前提条件,然后在没有理由继续进行匹配的路由时将控制权传递给后续路由.

以下代码段说明了可能的最简单的路由定义. Express将路径字符串转换为正则表达式,在内部用于匹配传入的请求. 执行这些匹配时考虑查询字符串,例如" GET /"将匹配以下路由," GET /?name = tobi"也将匹配.

router.get('/', function (req, res) {
  res.send('hello world')
})

您也可以使用正则表达式-如果您有非常特定的约束,则很有用,例如,以下内容将匹配" GET / commits / 71dbb9c"和" GET /commits/71dbb9c..4c084f9".

router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function (req, res) {
  const from = req.params[0]
  const to = req.params[1] || 'HEAD'
  res.send('commit range ' + from + '..' + to)
})

您可以基于特定的程序状态,使用next原语在不同的中间件功能之间实现流控制. next使用字符串'router'调用将导致绕过该路由器上的所有其余路由回调.

以下示例说明了next('router')用法.

function fn (req, res, next) {
  console.log('I come here')
  next('router')
}
router.get('/foo', fn, function (req, res, next) {
  console.log('I dont come here')
})
router.get('/foo', function (req, res, next) {
  console.log('I dont come here')
})
app.get('/foo', function (req, res) {
  console.log(' I come here too')
  res.end('good')
})

router.param(name, callback)

将回调触发器添加到路由参数,其中name是参数的名称, callback是回调函数. 尽管name在技​​术上是可选的,但从Express v4.11.0开始,不建议使用不带name的方法(请参见下文).

回调函数的参数为​​:

  • req ,请求对象.
  • res ,响应对象.
  • next, indicating the next middleware function.
  • name参数的值.
  • 参数的名称.

app.param()不同, router.param()不接受路由参数数组.

例如,当:user存在于路径路径中时,您可以映射用户加载逻辑以自动将req.user提供给路径,或对参数输入执行验证.

router.param('user', function (req, res, next, id) {
  // try to get the user details from the User model and attach it to the request object
  User.find(id, function (err, user) {
    if (err) {
      next(err)
    } else if (user) {
      req.user = user
      next()
    } else {
      next(new Error('failed to load user'))
    }
  })
})

参数回调函数对于定义它们的路由器而言是本地的. 它们不会被已安装的应用程序或路由器继承. 因此, router定义的参数回调仅由router路由上定义的路由参数触发.

即使参数在多个路由中匹配,在请求-响应周期中也仅会调用一次参数回调,如以下示例所示.

router.param('id', function (req, res, next, id) {
  console.log('CALLED ONLY ONCE')
  next()
})

router.get('/user/:id', function (req, res, next) {
  console.log('although this matches')
  next()
})

router.get('/user/:id', function (req, res) {
  console.log('and this matches too')
  res.end()
})

On GET /user/42, the following is printed:

CALLED ONLY ONCE
although this matches
and this matches too

以下部分描述了router.param(callback) ,从v4.11.0开始不推荐使用.

通过仅将一个函数传递给router.param()可以完全改变router.param(name, callback)方法的行为. 此函数是router.param(name, callback)行为的自定义实现-它接受两个参数,并且必须返回中间件.

此函数的第一个参数是应捕获的URL参数的名称,第二个参数可以是可用于返回中间件实现的任何JavaScript对象.

函数返回的中间件决定了捕获URL参数时所发生的行为.

在此示例中,将router.param(name, callback)签名修改为router.param(name, accessId) . router.param()现在将接受名称和数字,而不是接受名称和回调.

const express = require('express')
const app = express()
const router = express.Router()

// customizing the behavior of router.param()
router.param(function (param, option) {
  return function (req, res, next, val) {
    if (val === option) {
      next()
    } else {
      res.sendStatus(403)
    }
  }
})

// using the customized router.param()
router.param('id', 1337)

// route to trigger the capture
router.get('/user/:id', function (req, res) {
  res.send('OK')
})

app.use(router)

app.listen(3000, function () {
  console.log('Ready')
})

在此示例中, router.param(name, callback)签名保持不变,但是已定义了自定义数据类型检查功能来验证用户ID的数据类型,而不是中间件回调.

router.param(function (param, validator) {
  return function (req, res, next, val) {
    if (validator(val)) {
      next()
    } else {
      res.sendStatus(403)
    }
  }
})

router.param('id', function (candidate) {
  return !isNaN(parseFloat(candidate)) && isFinite(candidate)
})

router.route(path)

返回单个路由的实例,然后您可以使用该路由使用可选的中间件来处理HTTP动词. 使用router.route()避免重复的路由命名,从而避免键入错误.

以下代码建立在上面的router.param()示例的基础上,显示了如何使用router.route()指定各种HTTP方法处理程序.

const router = express.Router()

router.param('user_id', function (req, res, next, id) {
  // sample user, would actually fetch from DB, etc...
  req.user = {
    id: id,
    name: 'TJ'
  }
  next()
})

router.route('/users/:user_id')
  .all(function (req, res, next) {
  // runs for all HTTP verbs first
  // think of it as route specific middleware!
    next()
  })
  .get(function (req, res, next) {
    res.json(req.user)
  })
  .put(function (req, res, next) {
  // just an example of maybe updating the user
    req.user.name = req.params.name
    // save user ... etc
    res.json(req.user)
  })
  .post(function (req, res, next) {
    next(new Error('not implemented'))
  })
  .delete(function (req, res, next) {
    next(new Error('not implemented'))
  })

这种方法重复使用了/users/:user_id路径,并为各种HTTP方法添加了处理程序.

注意:使用router.route() ,中间件排序基于创建路由的时间,而不是基于将方法处理程序添加到路由的时间. 为此,您可以考虑方法处理程序属于它们添加到的路由.

router.use([path], [function, ...] function)

使用指定的一个或多个中间件函数,以及可选的安装路径path ,默认为" /".

此方法类似于app.use() . 下面描述了一个简单的示例和用例. 有关更多信息,请参见app.use() .

中间件就像管道:请求从定义的第一个中间件功能开始,并按照它们匹配的每个路径"向下"进行中间件堆栈处理.

const express = require('express')
const app = express()
const router = express.Router()

// simple logger for this router's requests
// all requests to this router will first hit this middleware
router.use(function (req, res, next) {
  console.log('%s %s %s', req.method, req.url, req.path)
  next()
})

// this will only be invoked if the path starts with /bar from the mount point
router.use('/bar', function (req, res, next) {
  // ... maybe some additional /bar logging ...
  next()
})

// always invoked
router.use(function (req, res, next) {
  res.send('Hello World')
})

app.use('/foo', router)

app.listen(3000)

"安装"路径已删除,并且对中间件功能可见. 此功能的主要作用是,无论其"前缀"路径名如何,安装的中间件功能都可以在不更改代码的情况下运行.

使用router.use()定义中间件的顺序非常重要. 它们被顺序调用,因此顺序定义了中间件优先级. 例如,通常记录器是您要使用的第一个中间件,因此每个请求都会被记录.

const logger = require('morgan')

router.use(logger())
router.use(express.static(path.join(__dirname, 'public')))
router.use(function (req, res) {
  res.send('Hello')
})

现在,假设您想忽略对静态文件的日志记录请求,但是继续记录在logger()之后定义的路由和中间件. 在添加记录器中间件之前,您只需将对express.static()的调用移到顶部即可:

router.use(express.static(path.join(__dirname, 'public')))
router.use(logger())
router.use(function (req, res) {
  res.send('Hello')
})

另一个示例是从多个目录提供文件,将" ./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')))

router.use()方法还支持命名参数,以便其他路由器的安装点可以受益于使用命名参数的预加载.

注意 :尽管这些中间件功能是通过特定的路由器添加的, 但是它们的运行时间是由它们附加到的路径(而不是路由器)定义的. 因此,如果一个路由器添加的中间件的路由匹配,则该中间件可以为其他路由器运行. 例如,此代码显示了安装在同一路径上的两个不同的路由器:

const authRouter = express.Router()
const openRouter = express.Router()

authRouter.use(require('./authenticate').basic(usersdb))

authRouter.get('/:user_id/edit', function (req, res, next) {
  // ... Edit user UI ...
})
openRouter.get('/', function (req, res, next) {
  // ... List users ...
})
openRouter.get('/:user_id', function (req, res, next) {
  // ... View user ...
})

app.use('/users', authRouter)
app.use('/users', openRouter)

即使经由所添加的认证中间件authRouter它将由所限定的路线运行openRouter ,以及因为两个路由器被安装在/users . 为避免此现象,请为每个路由器使用不同的路径.

by  ICOPY.SITE