API

Express

express()

创建一个Express应用程序。该express()函数是express模块导出的顶级函数。

var express = require('express' var app = express(

方法

express.json(options)

该中间件在Express v4.16.0及之后版本中提供。

这是Express中内置的中间件功能。它使用JSON有效负载分析传入请求,并基于body-parser

返回仅分析JSON并仅查看Content-Type标题与type选项匹配的请求中间件。该解析器接受body的任何Unicode编码并支持以gzipdeflate方式的自动压缩。

body包含解析数据的新对象request在中间件(ie req.body)之后被填充到对象上,或者{}如果没有要解析的主体,Content-Type则不匹配或发生错误,则会填充空对象()。

下表介绍了可选options对象的属性。

属性描述类型默认
inflate启用或禁用处理放气(压缩)的物体;当禁用时,放气的物体被拒绝。Booleantrue
limit控制最大请求主体大小。如果这是一个数字,那么该值指定字节数;如果它是一个字符串,则将该值传递给字节库以供解析。Mixed“100kb”
reviver作为第二个参数,reviver选项直接传递给JSON.parse。您可以在关于JSON.parse的MDN文档中找到关于此参数的更多信息。Functionnull
strict启用或禁用只接受数组和对象; 禁用时将接受JSON.parse接受的任何内容。Booleantrue
type这用于确定中间件将解析的媒体类型。该选项可以是字符串,字符串数组或函数。如果不是函数,则type选项直接传递到类型库,这可以是扩展名(如json),MIME类型(如application / json)或带有通配符的MIME类型(如* / *或* / json)。如果一个函数,类型选项被称为fn(req),并且如果它返回一个真值,则请求被解析。Mixed"application/json"
verify如果提供此选项,则称为verify(req,res,buf,encoding),其中buf是原始请求主体的缓冲区,编码是请求的编码。解析可以通过抛出错误来中止。Functionundefined

express.static(root, options)

这是Express中内置的中间件功能。它提供静态文件并基于服务静态

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

root参数指定要从中为静态资产提供服务的根目录。该功能通过req.url与提供的root目录结合来确定要提供的文件。当找不到文件时,它不是发送404响应,而是调用next()移动到下一个中​​间件,允许堆叠和回退。

下表介绍了该options对象的属性。另见下面的例子。

PropertyDescriptionTypeDefault
dotfiles 确定如何处理点文件(以“。”开头的文件或目录)。请参阅下面的dotfiles。 String“ignore”
etag 启用或禁用etag生成注意:express.static总是发送弱ETags。 Booleantrue
extensions 设置文件扩展名回退:如果找不到文件,请搜索具有指定扩展名的文件并提供找到的第一个文件。例如:'html','htm'。 Mixedfalse
fallthrough 让客户端错误作为未处理的请求发生,否则转发客户端错误。请参阅下面的下文。 Booleantrue
immutable 在Cache-Control响应头中启用或禁用不可变指令。如果启用,还应指定maxAge选项以启用缓存。不可变的指令将阻止受支持的客户端在maxAge选项生命期间发出条件请求,以检查文件是否已更改。 Booleanfalse
index 发送指定的目录索引文件。设置为false以禁用目录索引。 Mixed“index.html”
lastModified 将Last-Modified标题设置为操作系统上文件的最后修改日期。 Booleantrue
maxAge 以毫秒为单位设置Cache-Control标头的max-age属性或以ms格式设置字符串。 Number0
redirect 当路径名称是目录时,重定向到尾随“/”。 Booleantrue
setHeaders 用于设置HTTP头文件的功能。请参阅下面的setHeaders。 Function

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

dotfiles

此选项的可能值为:

  • “allow” - 没有针对dotfiles的特殊处理。

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

fallthrough

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

设置此选项为true,以便您可以将多个物理目录映射到相同的Web地址或路径以填充不存在的文件。

如果您已经将该中间件安装在严格意义上为单个文件系统目录的路径中,则可以使用false路径,从而可以短接404s以减少压力。这个中间件也会回复所有的方法。

setHeaders

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

该函数的签名是:

fn(res, path, stat)

参数:

  • res,响应对象。

express.static的示例

下面是一个使用express.static中间件功能和精心设计的选项对象的例子:

var 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)

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

var router = express.Router([options]

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

属性描述默认可用性
caseSensitive启用区分大小写。默认情况下禁用,将“/ Foo”和“/ foo”视为相同。
mergeParams保留父路由器的req.params值。如果父和子有相互冲突的参数名称,则该子的值优先。false4.5.0+
strict启用严格的路由。默认情况下,“/ foo”和“/ foo /”被路由器视为相同。

您可以添加中间件和HTTP方法路由(如getputpost,等),以router就像一个应用程序。

有关更多信息,请参阅路由器。

express.urlencoded(options)

该中间件在Express v4.16.0及之后版本中提供。

这是Express中内置的中间件功能。它使用urlencoded有效负载分析传入请求,并基于body-parser

返回仅分析urlencoded主体的中间件,并仅查看Content-Type标题与type选项匹配的请求。该解析器只接受身体的UTF-8编码,并支持自动膨胀gzipdeflate编码。

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

下表介绍了可选options对象的属性。

属性描述类型默认
extended此选项允许选择使用查询字符串库(如果为false)或qs库(如果为true)解析URL编码数据。“扩展”语法允许将丰富的对象和数组编码为URL编码格式,从而允许使用URL编码的类似JSON的体验。有关更多信息,请参阅qs资料库。Booleantrue
inflate启用或禁用处理放气(压缩)的物体; 当禁用时,放气的身体被拒绝。Booleantrue
limit控制最大请求主体大小。如果这是一个数字,那么该值指定字节数; 如果它是一个字符串,则将该值传递给字节库以供解析。Mixed“100kb”
parameterLimit该选项控制URL编码数据中允许的最大参数数量。如果请求包含的参数多于此值,则会引发错误。Number1000
type这用于确定中间件将解析的媒体类型。该选项可以是字符串,字符串数组或函数。如果不是函数,则type选项将直接传递到type-is库,这可以是扩展名(如urlencoded),MIME类型(如application / x-www-form-urlencoded)或带MIME类型的MIME类型通配符(如* / x-www-form-urlencoded)。如果一个函数,类型选项被称为fn(req),并且如果它返回一个真值,则请求被解析。Mixed "application/x-www-form-urlencoded"
verify如果提供此选项,则称为verify(req,res,buf,encoding),其中buf是原始请求主体的缓冲区,编码是请求的编码。解析可以通过抛出错误来中止。Functionundefined

应用

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

var express = require('express' var app = express( app.get('/', function(req, res){ res.send('hello world' } app.listen(3000

app对象有方法

  • 路由HTTP请求;例如,请参阅app.METHOD和app.param。

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

Express应用程序对象可以根据请求对象和响应对象被称为对应的req.app,和res.app

属性

app.locals

app.locals对象的属性是应用程序中的局部变量。

app.locals.title // => 'My App' app.locals.email // => 'me@myapp.com'

一旦设置,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可以用于处理对路线的请求的实例。

var express = require('express' var app = express( // the main app var 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

它类似于req对象的baseUrl属性,除了req.baseUrl返回匹配的URL路径,而不是匹配的模式。

如果子应用程序安装在多个路径模式中,则app.mountpath返回它所加载的模式列表,如以下示例所示。

var admin = express( admin.get('/', function (req, res) { console.log(admin.mountpath // [ '/adm*n', '/manager' ] res.send('Admin Homepage' } var 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.on('mount', callback(parent))

mount事件是在子应用,当它被安装在一个父应用程序。父应用程序被传递给回调函数。

注意

子应用程序将:

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

有关详情,请参阅应用程序设置

var 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

方法

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

此方法与标准的app.METHOD()方法类似,只不过它匹配所有HTTP动词。

参数

参数描述默认
path中间件功能被调用的路径; 可以是以下任何一种:表示路径的字符串。路径模式。一个正则表达式模式来匹配路径。上述任何组合的数组。有关示例,请参阅路径示例。 '/' (root path)
callback回调函数; 可以是:中间件功能。一系列中间件功能(用逗号分隔)。一系列中间件功能。以上所有组合。您可以提供多个回调函数,其行为就像中间件一样,只不过这些回调可以调用next('route')来绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。由于路由器和应用程序实现了中间件接口,因此您可以像使用其他中间件功能一样使用它们。有关示例,请参阅中间件回调函数示例。None

  • 表示路径的字符串。

有关示例,请参阅路径示例。'/'(根路径)callback回调函数;可以是:

  • 中间件功能。

您可以提供多个回调函数,其行为与中间件类似,只是这些回调可以调用next('route')绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。

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

有关示例,请参阅中间件回调函数示例。

示例

以下回调针对/secret使用GET,POST,PUT,DELETE或任何其他HTTP请求方法的请求执行:

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

另一个例子是白名单“global”功能。这个例子与上面的例子类似,但它仅限制以“/ api”开头的路径:

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

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

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

参数

参数描述默认
path中间件功能被调用的路径;可以是以下任何一种:表示路径的字符串。路径模式。一个正则表达式模式来匹配路径。上述任何组合的数组。有关示例,请参阅路径示例。 '/' (root path)
callback回调函数;可以是:中间件功能、一系列中间件功能(用逗号分隔)、一系列中间件功能、以上所有组合。您可以提供多个回调函数,其行为就像中间件一样,只不过这些回调可以调用next('route')来绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。由于路由器和应用程序实现了中间件接口,因此您可以像使用其他中间件功能一样使用它们。有关示例,请参阅中间件回调函数示例。None

  • 表示路径的字符串。

有关示例,请参阅路径示例。'/'(根路径)callback回调函数; 可以是:

  • 中间件功能。

您可以提供多个回调函数,其行为与中间件类似,只是这些回调可以调用next('route')绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。

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

有关示例,请参阅中间件回调函数示例。

示例

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

app.disable(name)

将布尔值设置namefalse,其中name是应用程序设置表中的其中一个属性。调用app.set('foo', false)作为布尔属性与调用app.disable('foo')相同。

例如:

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

app.disabled(name)

如果布尔设置name被禁用(false),返回true。其中name是应用程序设置表中的一个属性。

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

app.enable(name)

将布尔值设置nametrue,其中name是应用程序设置表中的其中一个属性。调用app.set('foo', true)布尔属性与调用app.enable('foo')相同。

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

app.enabled(name)

如果name启用了设置(true),返回true,其中name是应用程序设置表中的其中一个属性。

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

app.engine(ext, callback)

将给定的模板引擎注册callbackext

默认情况下,Express会根据文件扩展名来require()引擎。例如,如果您尝试呈现“foo.pug”文件,则Express会在内部调用以下内容,并在随后的调用中缓存require()以提高性能。

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

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

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

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

在这种情况下,EJS提供了一个具有Express期望的相同签名(path, options, callback).renderFile()方法,但请注意,它在ejs.__express内部将此方法进行了别名,因此如果使用“.ejs”扩展名,则不需要执行任何操作。

Some template engines do not follow this convention. The consolidate.js library maps Node template engines to follow this convention, so they work seamlessly with Express.

var 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请求路由到指定的路径。

参数

参数描述默认
path中间件功能被调用的路径;可以是以下任何一种:表示路径的字符串、路径模式。一个正则表达式模式来匹配路径。上述任何组合的数组。有关示例,请参阅路径示例。 '/' (root path)
callback回调函数;可以是:中间件功能。一系列中间件功能(用逗号分隔)。一系列中间件功能。以上所有组合。您可以提供多个回调函数,其行为就像中间件一样,只不过这些回调可以调用next('route')来绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。由于路由器和应用程序实现了中间件接口,因此您可以像使用其他中间件功能一样使用它们。有关示例,请参阅中间件回调函数示例。None

  • 表示路径的字符串。

For examples, see Path examples. '/' (root path) callback Callback functions; can be:

  • 中间件功能。

您可以提供多个回调函数,其行为与中间件类似,只是这些回调可以调用next('route')绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。

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

有关示例,请参阅中间件回调函数示例。

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

示例

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

app.listen(path, callback)

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

var express = require('express' var app = express( app.listen('/tmp/sock'

app.listen(port, hostname, backlog, callback)

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

var express = require('express' var app = express( app.listen(3000

app返回的express()实际上是一个JavaScript Function,旨在传递到节点的HTTP服务器作为一个回调来处理请求。这使得您可以轻松地使用相同的代码库为您的应用程序提供HTTP和HTTPS版本,因为应用程序不会从这些应用程序继承(它只是一个回调):

var express = require('express' var https = require('https' var http = require('http' var 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 };

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

路由HTTP请求,其中METHOD是请求的HTTP方法,例如GET,PUT,POST等,小写形式。因此,实际的方法是app.get()app.post()app.put(),等等。请参阅下面的路由方法以获取完整列表。

参数

参数描述默认
path中间件功能被调用的路径; 可以是以下任何一种:表示路径的字符串。路径模式。一个正则表达式模式来匹配路径。上述任何组合的数组。有关示例,请参阅路径示例。 '/' (root path)
callback回调函数;可以是:中间件功能。一系列中间件功能(用逗号分隔)。一系列中间件功能。以上所有组合。您可以提供多个回调函数,其行为就像中间件一样,只不过这些回调可以调用next('route')来绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。由于路由器和应用程序实现了中间件接口,因此您可以像使用其他中间件功能一样使用它们。有关示例,请参阅中间件回调函数示例。None

  • 表示路径的字符串。

有关示例,请参阅路径示例 '/' (root path) callback 回调函数;可以是:

  • 中间件功能。

您可以提供多个回调函数,其行为与中间件类似,只是这些回调可以调用next('route')绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。

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

有关示例,请参阅中间件回调函数示例。

路由方法

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

checkout copy delete get head lock merge mkactivitymkcol move m-search notify options patch postpurge put report search subscribe trace unlock unsubscribe

  • checkout

API文档中有明确的项目只针对最流行的HTTP方法app.get()app.post()app.put(),和app.delete()。但是,上面列出的其他方法的工作方式完全相同。

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

除了GET方法之外,如果以前app.head()没有在app.get()之前被路径app.get()调用该函数,则会自动为HTTP HEAD方法调用该函数。

方法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') } } }

Param回调函数在它们被定义的路由器的本地。它们不会被安装的应用程序或路由器继承。因此,定义的参数回调app将仅由路由上定义的路由参数触发app

所有param回调函数都将在param出现的任何路由的任何处理程序之前被调用,并且它们将在请求 - 响应循环中仅被调用一次,即使参数在多个路由中匹配,如以下示例所示。

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.param(callback)从v4.11.0开始不推荐使用的部分。

app.param(name, callback)方法的行为可以完全通过只传递一个函数来改变app.param()。这个函数是一个app.param(name, callback)应该如何行为的自定义实现- 它接受两个参数并且必须返回一个中间件。

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

该函数返回的中间件决定捕获URL参数时发生的行为。

在这个例子中,app.param(name, callback)签名被修改为app.param(name, accessId)app.param()现在接受一个名字和一个数字,而不是接受一个名字和一个回调。

var express = require('express' var app = express( // customizing the behavior of app.param() app.param(function(param, option) { return function (req, res, next, val) { if (val == option) { next( } else { next('route' } } } // using the customized app.param() app.param('id', 1337 // route to trigger the capture app.get('/user/:id', function (req, res) { res.send('OK' } app.listen(3000, function () { console.log('Ready' }

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

app.param(function(param, validator) { return function (req, res, next, val) { if (validator(val)) { next( } else { next('route' } } } app.param('id', function (candidate) { return !isNaN(parseFloat(candidate)) && isFinite(candidate }

' .'字符不能用于捕获捕获正则表达式中的字符。例如,你不能用'/user-.+/'来捕捉'users-gami',用[\\s\\S][\\w\\W]改为(如'/user-[\\s\\S]+/'

示例:

//captures '1-a_6' but not '543-azser-sder' router.get('/[0-9]+-[[\\w]]*', function //captures '1-a_6' and '543-az(ser"-sder' but not '5-a s' router.get('/[0-9]+-[[\\S]]*', function //captures all (equivalent to '.*') router.get('[[\\s\\S]]*', function

app.path()

返回应用程序的规范路径,一个字符串。

var app = express() , blog = express() , 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请求路由到指定的路径。有关更多信息,请参阅路由指南

参数

参数描述默认
path中间件功能被调用的路径;可以是以下任何一种:表示路径的字符串、路径模式和正则表达式模式来匹配路径,或上述任何组合的数组。有关示例,请参阅路径示例。 '/' (root path)
callback回调函数;可以是:中间件功能、一系列中间件功能(用逗号分隔)、一系列中间件功能,或以上所有组合。您可以提供多个回调函数,其行为就像中间件一样,只不过这些回调可以调用next('route')来绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。由于路由器和应用程序实现了中间件接口,因此您可以像使用其他中间件功能一样使用它们。有关示例,请参阅中间件回调函数示例。None

  • 表示路径的字符串。

有关示例,请参阅路径示例,'/' (root path) callback回调函数;可以是:

  • 中间件功能。

您可以提供多个回调函数,其行为与中间件类似,只是这些回调可以调用next('route')绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。

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

有关示例,请参阅中间件回调函数示例。

示例

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

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

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

参数

参数描述默认
path中间件功能被调用的路径;可以是以下任何一种:表示路径的字符串、路径模式、一个正则表达式模式来匹配路径以及上述任何组合的数组。有关示例,请参阅路径示例。 '/' (root path)
callback回调函数;可以是:中间件功能、一系列中间件功能(用逗号分隔)、一系列中间件功能,及以上所有组合。您可以提供多个回调函数,其行为就像中间件一样,只不过这些回调可以调用next('route')来绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。由于路由器和应用程序实现了中间件接口,因此您可以像使用其他中间件功能一样使用它们。有关示例,请参阅中间件回调函数示例。None

  • 表示路径的字符串。

有关示例,请参阅路径示例。 '/' (root path)callback回调函数; 可以是:

  • 中间件功能。

您可以提供多个回调函数,其行为与中间件类似,只是这些回调可以调用next('route')绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。

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

有关示例,请参阅中间件回调函数示例。

示例

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)

返回单个路由的实例,然后您可以使用该实例来处理具有可选中间件的HTTP动词。使用app.route()以避免重复路线名称(因此出现打字错误)。

var 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)

分配设置namevalue。您可以存储您想要的任何值,但某些名称可用于配置服务器的行为。这些特殊名称在应用程序设置表中列出。

调用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"

应用程序设置

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

请注意,子应用程序将:

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

例外情况:子应用程序将继承trust proxy的值,即使它具有默认值(用于向后兼容)。子应用程序不会继承view cache生产中的价值(当NODE_ENV是“production”)。

属性类型描述默认
case sensitive routing布尔启用区分大小写。启用时,“/ Foo”和“/ foo”是不同的路线。禁用时,“/ Foo”和“/ foo”的处理方式相同。注意:子应用程序将继承此设置的值。 N/A (undefined)
env环境模式。确保在生产环境中设置为“生产”; 请参阅生产最佳实践:性能和可靠性。 process.env.NODE_ENV (NODE_ENV environment variable) or “development” if NODE_ENV is not set.
etag多变设置ETag响应标题。有关可能的值,请参阅etag选项表。有关HTTP ETag标头的更多信息。 weak
jsonp callback name指定默认的JSONP回调名称。 “callback”
json escape布尔启用从res.json,res.jsonp和res.send API转义的JSON响应。这将在JSON中转义字符<,>和&作为Unicode转义序列。这样做的目的是当客户端嗅探HTML响应时协助减轻某些类型的持续XSS攻击。注意:子应用程序将继承此设置的值。 N/A (undefined)
json replacer多变'替代者'论证使用的JSON.stringify。注意:子应用程序将继承此设置的值。 N/A (undefined)
json spaces多变“空间”论证使用JSON.stringify。这通常设置为用于缩进美化JSON的空格数量。注意:子应用程序将继承此设置的值。 N/A (undefined)
query parser多变通过将该值设置为false来禁用查询分析,或者将查询分析器设置为使用“简单”或“扩展”或自定义查询字符串分析功能。简单的查询解析器基于Node的本地查询解析器querystring。扩展查询解析器基于qs。自定义查询字符串解析函数将接收完整的查询字符串,并且必须返回查询关键字及其值的对象。 "extended"
strict routing布尔启用严格的路由。启用时,路由器将“/ foo”和“/ foo /”视为不同。否则,路由器将“/ foo”和“/ foo /”视为相同。注意:子应用程序将继承此设置的值。 N/A (undefined)
subdomain offset要移除以访问子域的主机的点分离部分的数量。2
trust proxy多变指示应用程序位于前置代理后面,并使用X-Forwarded- *标题确定客户端的连接和IP地址。注:X-Forwarded- *标头很容易被欺骗,检测到的IP地址不可靠。启用后,Express会尝试确定通过前置代理或一系列代理连接的客户端的IP地址。该req.ips属性然后包含客户端连接的一组IP地址。要启用它,请使用信任代理选项表中描述的值。该trust proxy设置是使用proxy-addr软件包实现的。有关更多信息,请参阅其文档。注:子应用程序将继承此设置的值,即使它具有默认值。 false (disabled)
views字符串或数组应用程序视图的目录或目录数组。如果是数组,那么视图按照它们在数组中出现的顺序查找。process.cwd()+'/ views'
view cache布尔启用视图模板编译缓存。注意:子应用程序不会继承生产中此设置的值(何时NODE\_ENV为“生产”)。 true in production, otherwise undefined.
view engine省略时使用的默认引擎扩展。注意:子应用程序将继承此设置的值。 N/A (undefined)
x-powered-by布尔启用“X-Powered-By:Express”HTTP标头。 true

  • loopback - 127.0.0.1/8, ::1/128

通过以下任何方式设置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 Trust the _n_th hop from the front-facing proxy server as the client.

Function Custom trust implementation. Use this only if you know what you are doing.

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软件包实现的。有关更多信息,请参阅其文档。

类型值布尔值 true启用弱ETag。这是默认设置。

false 完全禁用ETag。

String If "strong", enables strong ETag.

如果“weak”,弱化ETag。函数自定义ETag函数的实现。只有当你知道你在做什么时才使用。

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

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

在指定的路径上安装指定的中间件功能或中间件功能:当请求的路径的基础匹配时,执行中间件功能path

参数

参数描述默认
path中间件功能被调用的路径;可以是以下任何一种:表示路径的字符串、路径模式、一个正则表达式模式来匹配路径、或上述任何组合的数组。有关示例,请参阅路径示例。 '/' (root path)
callback回调函数; 可以是:中间件功能、一系列中间件功能(用逗号分隔)、一系列中间件功能、或以上所有组合。您可以提供多个回调函数,其行为就像中间件一样,只不过这些回调可以调用next('route')来绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。由于路由器和应用程序实现了中间件接口,因此您可以像使用其他中间件功能一样使用它们。有关示例,请参阅中间件回调函数示例。None

  • 表示路径的字符串。

有关示例,请参阅路径示例'/' (root path)callback回调函数;可以是:

  • 中间件功能。

您可以提供多个回调函数,其行为与中间件类似,只是这些回调可以调用next('route')绕过剩余的路由回调。您可以使用此机制在路线上施加先决条件,并在没有理由继续使用当前路线时将控制权交给后续路线。

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

For examples, see Middleware callback function examples.

描述

一条路径将立即匹配其路径后跟一个“ /”的任何路径。例如:app.use('/apple', ...)将匹配“/ apple”,“/ apple / images”,“/ apple / images / news”等。

由于path缺省设置为“/”,因此无需路径安装的中间件将针对应用程序的每个请求执行。

例如,该中间件功能将针对应用程序的每个请求执行:

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

注意

子应用程序将:

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

有关详情,请参阅应用程序设置

中间件功能是按顺序执行的,因此中间件包含的顺序非常重要。

// 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有关安装中间件的有效值的简单示例。

类型示例
路径这将匹配从以下开始的路径/abcd:app.use('/ abcd',function(req,res,next){next();});
路径模式这将匹配以/abcd和开头的路径/abd:app.use('/ abc?d',function(req,res,next){next();}); 这将匹配开始路径/abcd,/abbcd,/abbbbbcd,等:app.use( '/ AB + CD',功能(REQ,RES,下一个){下一个();}); 这将匹配开始路径/abcd,/abxcd,/abFOOcd,/abbArcd,等:app.use( '/ AB \ * CD',功能(REQ,RES,下一个){下一个();}); 这将匹配以/ad和开头的路径/abcd:app.use('/ a(bc)?d',function(req,res,next){next();});
正则表达式这将匹配以/abc和开头的路径/xyz:app.use(/ \ / abc | \ / xyz /,function(req,res,next){next();});
排列这将匹配的路径开始/abcd,/xyza,/lmn,和/pqr:app.use( '/ ABCD', '/ XYZA',/ \ / LMN | \ / PQR /,功能(REQ,RES,下一个){下一个();}) ;

中间件回调函数示例

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

用法示例
单一中间件您可以在本地定义和安装中间件功能。app.use(function(req,res,next){next();}); 路由器是有效的中间件。var router = express.Router(); router.get('/',function(req,res,next){next();}); app.use(路由器); Express应用程序是有效的中间件。var subApp = express(); subApp.get('/',function(req,res,next){next();}); app.use(subApp);
中间件系列您可以在相同的装载路径中指定多个中间件功能。var r1 = express.Router(); r1.get('/',function(req,res,next){next();}); var r2 = express.Router(); r2.get('/',function(req,res,next){next();}); app.use(r1,r2);
排列使用数组从逻辑上将中间件分组。如果您将一组中间件作为第一个或唯一的中间件参数传递,那么您必须指定安装路径。var r1 = express.Router(); r1.get('/',function(req,res,next){next();}); var r2 = express.Router(); r2.get('/',function(req,res,next){next();}); app.use('/',r1,r2);
组合您可以结合上述所有安装中间件的方式。函数mw1(req,res,next){next(); }函数mw2(req,res,next){next(); } var r1 = express.Router(); r1.get('/',function(req,res,next){next();}); var r2 = express.Router(); r2.get('/',function(req,res,next){next();}); var 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(__dirname + '/public')

仅当中间件的请求路径前缀为“/ static”时,才将中间件装入“/ static”以提供静态内容:

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

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

app.use(express.static(__dirname + '/public') app.use(logger()

从多个目录提供静态文件,但优先于其他目录的“./public”:

app.use(express.static(__dirname + '/public') app.use(express.static(__dirname + '/files') app.use(express.static(__dirname + '/uploads')

请求

req对象表示HTTP请求,并具有请求查询字符串,参数,正文,HTTP标头等的属性。在本文档中,按照惯例,该对象总是被称为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自身请求对象的增强版本,并支持所有内置字段和方法。

属性

在Express 4中,默认情况下req.filesreq对象中不再可用。要访问req.files对象上的上传文件,请使用多部件处理中间件,如busboy,multer,formidable,multiparty,connect-multiparty或pez。

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返回匹配的路径模式。

例如:

var 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属性也会返回匹配的字符串,而不是模式。在以下示例中,greet路由器以两种路径模式加载。

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

当向/greet/jpreq.baseUrl提出的请求是“/greet”。当向/hello/jp提出的请求是,req.baseUrl是“/ hello”。

req.body

包含请求正文中提交的键值对数据。默认情况下,是undefined。使用body-parser和multer等body分析中间件时被填充。

以下示例显示如何使用body分析中间件来填充req.body

var app = require('express')( var bodyParser = require('body-parser' var multer = require('multer' // v1.0.5 var 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 req.cookies.name // => "tj"

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

有关更多信息,问题或疑虑,请参阅cookie解析器

req.fresh

指示请求是否为“fresh”。与此相反req.stale

如果cache-control请求头没有no-cache指令并且下列任何一个都为真,那么这是真的:

  • if-modified-since请求标头中指定和last-modified请求标头是等于或早于modified响应。

req.fresh // => true

有关更多信息,问题或疑虑,请参阅全新

req.hostname

包含从HostHTTP头派生的主机名。

trust proxy设置不计算时false,此属性将改为具有X-Forwarded-Host标题字段的值。这个标头可以由客户端或代理来设置。

// Host: "example.com:3000" req.hostname // => "example.com"

req.ip

包含请求的远程IP地址。

trust proxy设置不计算到false时,此属性的值将从头中最左边的条目派生X-Forwarded-For。这个标头可以由客户端或代理来设置。

req.ip // => "127.0.0.1"

req.ips

trust proxy设置不计算false时,该属性包含X-Forwarded-For请求头中指定的IP地址数组。否则,它包含一个空数组。这个头可以由客户端或代理来设置。

例如,如果X-Forwarded-Forclient, proxy1, proxy2req.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 req.originalUrl // => "/search?q=something"

在中间件功能,req.originalUrl是的组合req.baseUrlreq.path,作为显示在下面的例子。

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

req.params

该属性是一个包含映射到指定路由“参数”的属性的对象。例如,如果您有路线/user/:name,那么“名称”属性可用req.params.name。该对象默认为{}

// GET /user/tj req.params.name // => "tj"

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

// GET /file/javascripts/jquery.js req.params[0] // => "javascripts/jquery.js"

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

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

req.path

包含请求URL的路径部分。

// example.com/users?sort=desc req.path // => "/users"

从中间件调用时,挂载点不包含在内req.path。有关更多详细信息,请参阅app.use()。

req.protocol

包含请求协议字符串:http或者(for TLES requests)https

如果trust proxy设置不计算为false,则此属性将使用X-Forwarded-Proto标题字段的值(如果存在)。这个标头可以由客户端或代理来设置。

req.protocol // => "http"

req.query

此属性是包含路由中每个查询字符串参数的属性的对象。如果没有查询字符串,它是空的对象,{}

// GET /search?q=tobi+ferret req.query.q // => "tobi ferret" // GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse req.query.order // => "desc" req.query.shoe.color // => "blue" req.query.shoe.type // => "converse"

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

一个Boolean属性,如果建立了TLS连接,则为true。相当于:

'https' == req.protocol;

req.signedCookies

当使用cookie解析器中间件时,该属性包含请求发送的签名cookie,未签名并可以使用。签名的cookies位于不同的对象中以显示开发者的意图;否则,可能会对req.cookie值进行恶意攻击(这很容易被欺骗)。请注意,签名cookie不会使其“隐藏”或加密;但只是防止篡改(因为用于签名的秘密是私密的)。

如果未发送签名的cookie,则属性默认为{}

// Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3 req.signedCookies.user // => "tobi"

有关更多信息,问题或疑虑,请参阅cookie解析器

req.stale

指示请求是否为“stale”,还是与之相反req.fresh。有关更多信息,请参阅req.fresh

req.stale // => true

req.subdomains

请求的域名中的一组子域。

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

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

req.xhr

一个布尔属性,true如果请求的X-Requested-With头部字段是“XMLHttpRequest”,则表示该请求是由诸如jQuery之类的客户端库发出的。

req.xhr // => true

方法

req.accepts(types)

根据请求的AcceptHTTP头字段检查指定的内容类型是否可接受。该方法返回最佳匹配,或者如果没有指定的内容类型是可接受的,则返回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' // => undefined // Accept: text/*;q=.5, application/json req.accepts(['html', 'json'] // => "json"

req.acceptsCharsets(charset , ...)

根据请求的Accept-CharsetHTTP头字段返回指定字符集的第一个接受字符集。如果没有指定的字符集被接受,则返回false

req.acceptsEncodings(encoding , ...)

根据请求的Accept-EncodingHTTP头字段返回指定编码的第一个可接受的编码。如果没有指定的编码被接受,则返回false

req.acceptsLanguages(lang , ...)

根据请求的Accept-LanguageHTTP头字段返回指定语言的第一个接受的语言。如果没有指定的语言被接受,则返回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.is(type)

如果传入请求的“Content-Type”HTTP标头字段与type参数指定的MIME类型相匹配,则返回匹配的内容类型。否则返回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

req.param(name , defaultValue)

已过时。二者必选其一req.paramsreq.bodyreq.query(如适用)。

当存在时返回参数name的值。

// ?name=tobi req.param('name') // => "tobi" // POST name=tobi req.param('name') // => "tobi" // /user/tobi for /user/:name req.param('name') // => "tobi"

查找按以下顺序执行:

  • req.params

或者,如果在任何请求对象中找不到该参数,则可以指定defaultValue设置默认值。

直接访问req.bodyreq.params以及req.query应该赞成清晰-除非你真正接受来自每个对象的输入。

body解析中间件必须被加载以便req.param()可预测地工作。详情请参阅req.body。

req.range(size, options)

Range 标头解析器。

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

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

属性类型描述
combineBoolean指定是否重叠和相邻范围应该组合,默认为false。如果为true,范围将被组合并返回,就像它们在标题中指定的那样。

将返回范围数组或表示错误解析的负数。

  • -2 表示格式错误的标题字符串

// parse header from request var 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 }) }

响应

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 }

res对象是Node自身响应对象的增强版本,并支持所有内置字段和方法。

属性

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( }

方法

res.append(field , value)

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

将指定的附加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标题字段设置为“附件”。如果给出filename,那么它通过扩展名设置Content-Type res.type(),并设置Content-Dispositionfilename =”参数。

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)

将cookiename设置为value。该value参数可能是一个字符串或对象转换为JSON。

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

属性类型描述
domainStringCookie的域名。默认为应用程序的域名。
encodeFunction用于cookie值编码的同步函数。默认为encodeURIComponent。
expiresDat以GMT格式的cookie的有效日期。如果未指定或设置为0,则创建会话cookie。
httpOnlyBoolean将cookie标记为仅可由Web服务器访问。
maxAgeNumber方便的选项,用于设置相对于当前时间的到期时间(以毫秒为单位)。
pathStringCookie的路径。默认为“/”。
secureBoolean将cookie标记为仅与HTTPS一起使用。
signedBoolean指示是否应该对cookie进行签名。
sameSitBoolean or String“SameSite”Set-Cookie属性的值。更多信息请访问https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1。

所有的res.cookie()操作都是Set-Cookie使用提供的选项设置HTTP 标头。任何未指定的选项都默认为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。只需将包含signed的选项设置为true即可。然后将使用res.cookie()传递给它的密码cookieParser(secret)来签名。

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

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

res.clearCookie(name , options)

通过name清除指定的cookie 。有关该options对象的详细信息,请参阅res.cookie()。

Web浏览器和其他兼容的客户端将只清除cookie,如果给定的options是给res.cookie(),排除expiresmaxAge

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

res.download(path , filename , fn)

options在Express v4.16.0及更高版本支持可选参数。

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)

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

用于快速结束没有任何数据的响应。如果您需要使用数据进行响应,请使用res.send()和res.json()等方法。

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

res.format(object)

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

Content-Type当选择一个回调响应首部设置。但是,您可以使用诸如res.set()或之类的方法在回调中修改此内容res.type()

下面的例子{ "message": "hey" }Accept头域被设置为“application / json”或“* / json”时响应(但是如果它是“* / *”,那么响应将是“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)

返回由指定的HTTP响应头field。不区分大小写。

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

res.json(body)

发送JSON响应。此方法使用JSON.stringify()将响应(使用正确的内容类型)作为参数转换为JSON字符串。

该参数可以是任何JSON类型,包括对象,数组,字符串,布尔值或数字,您也可以使用它将其他值转换为JSON,例如nullundefined(尽管这些在技术上无效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" })

res.links(links)

连接links提供的参数属性以填充响应的LinkHTTP标头字段。

For example, the following call:

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)

将响应LocationHTTP标头设置为指定的path参数。

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

path“后”的值具有特殊的含义,它指的是在指定的URL Referer的请求的报头中。如果Referer未指定标题,则表示“/”。

对URL进行编码后,如果尚未编码,Express会将指定的URL传递到Location标头中的浏览器,而不进行任何验证。

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

res.redirect(status, path)

重定向到从指定的URL派生的URL path,带有指定的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'

重定向到post/newhttp://example.com/blog/admin(没有尾随斜线),会重定向到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)

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

  • locals,其属性定义视图的局部变量的对象。

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(new Buffer('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-LengthHTTP响应头字段(除非先前已定义),并提供自动HEAD和HTTP缓存新鲜度支持。

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

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

当参数是String时,该方法设置Content-Type为“text / html”:

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

当参数是Array或者Object时,Express以JSON表示响应:

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

res.sendFile(path , options)

res.sendFile() 由Express v4.8.0起支持。

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

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

属性描述默认可用性
MAXAGE以毫秒为单位设置Cache-Control标头的max-age属性,或以ms格式设置字符串0
root相对文件名的根目录。
lastModified 将Last-Modified标头设置为OS上文件的最后修改日期。设置为false将其禁用。启用4.9.0+
headers 包含HTTP标头的对象以与该文件一起提供。
dotfiles 提供点文件的选项。可能的值是“允许”,“拒绝”,“忽略”。“忽视”
acceptRanges启用或禁用接受范围的请求。真正4.14+
CacheControl启用或禁用设置缓存控制响应头。真正4.14+
一成不变在Cache-Control响应头中启用或禁用不可变指令。如果启用,还应指定maxAge选项以启用缓存。不可变的指令将阻止受支持的客户端在maxAge选项生命期间发出条件请求,以检查文件是否已更改。4.16+

fn(err)方法在传输完成或发生错误时调用回调函数。如果指定了回调函数并且发生错误,则回调函数必须通过结束请求 - 响应循环或将控制权交给下一个路径来显式处理响应过程。

这是一个使用res.sendFile所有参数的例子。

app.get('/file/:name', function (req, res, next) { var options = { root: __dirname + '/public/', dotfiles: 'deny', headers: { 'x-timestamp': Date.now(), 'x-sent': true } }; var 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){ var uid = req.params.uid , 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." } } }

有关更多信息,或者如果您有问题或疑虑,请参阅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.sendStatus(2000 // equivalent to res.status(2000).send('2000')

res.set(field , value)

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

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

别名为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类型mime.lookup()为指定的type。如果type包含“/”字符,则将Content-Type设置为type

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对象是一个孤立的中间件和路由实例。您可以将其视为只能执行中间件和路由功能的“小型应用程序”。每个Express应用程序都有一个内置的应用程序路由器。

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

顶层express对象有一个Router()创建新router对象的方法。

一旦你创建了一个路由器的对象,你可以添加中间件和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) { // .. }

然后,您可以通过这种方式将路由器用于特定的根网址,将路线分隔为文件甚至迷你应用程序。

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

方法

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

这个方法就像router.METHOD()一样,只是它匹配所有的HTTP方法(动词)。

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

router.all('*', requireAuthentication, loadUser

或者相当于:

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

Another example of this is white-listed “global” functionality. Here the example is much like before, but it only restricts paths prefixed with “/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()调用函数GETrouter.head(),则会自动为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){ var from = req.params[0]; var to = req.params[1] || 'HEAD'; res.send('commit range ' + from + '..' + to }

router.param(name, callback)

添加回调触发器来设置路由参数,其中name是参数的名称并且callback是回调函数。尽管name在技​​术上是可选的,但使用这种没有它的方法已经被弃用,从Express v4.11.0开始(见下文)。

回调函数的参数是:

  • req,请求对象。

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

Param回调函数在它们被定义的路由器的本地。它们不会被安装的应用程序或路由器继承。因此,定义的参数回调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( }

GET /user/42,打印如下:

CALLED ONLY ONCE although this matches and this matches too

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

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

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

该函数返回的中间件决定捕获URL参数时发生的行为。

在这个例子中,router.param(name, callback)签名被修改为router.param(name, accessId)router.param()现在接受一个名字和一个数字,而不是接受一个名字和一个回叫。

var express = require('express' var app = express( var 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)签名保持不变,但不是中间件回调,而是定义了自定义数据类型检查函数来验证用户标识的数据类型。

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方法处理程序。

var 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()。

中间件就像一个管道:请求从定义的第一个中间件功能开始,并为他们匹配的每个路径“下”中间件堆栈处理。

var express = require('express' var app = express( var 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()定义中间件的顺序非常重要。它们是按顺序调用的,因此顺序定义了中间件的优先级。例如,通常记录器是您要使用的第一个中间件,这样每个请求都会被记录下来。

var logger = require('morgan' router.use(logger() router.use(express.static(__dirname + '/public') router.use(function(req, res){ res.send('Hello' }

现在假设您想忽略对静态文件的记录请求,但要继续记录之后定义的路由和中间件logger()。在添加记录器中间件之前,您只需将呼叫express.static()移至顶端即可:

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

另一个例子是提供来自多个目录的文件,优先于其他文件的“./public”:

app.use(express.static(__dirname + '/public') app.use(express.static(__dirname + '/files') app.use(express.static(__dirname + '/uploads')

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

注意:虽然这些中间件功能是通过特定路由器添加的,但它们运行时由其所连接的路径(而不是路由器)定义。因此,如果路由匹配,通过一台路由器添加的中间件可能会为其他路由器运行。例如,此代码显示了在同一路径上安装的两个不同的路由器:

var authRouter = express.Router( var 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。为了避免这种情况,请为每个路由器使用不同的路径。