You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
varexpress=require('express');varapp=express();// the main appvaradmin=express();// the sub appadmin.get('/',function(req,res){console.log(admin.mountpath);// /adminres.send('Admin Homepage');});app.use('/admin',admin);// mount the sub app
varadmin=express();admin.get('/',function(req,res){console.log(admin.mountpath);// [ '/adm*n', '/manager' ]res.send('Admin Homepage');});varsecret=express();secret.get('/',function(req,res){console.log(secret.mountpath);// /secr*tres.send('Admin Secret');});admin.use('/secr*t',secret);// load the 'secret' router on '/secr*t', on the 'admin' sub appapp.use(['/adm*n','/manager'],admin);// load the 'admin' router on '/adm*n' and '/manager', on the parent app
varadmin=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.param('user',function(req,res,next,id){// try to get the user details from the User model and attach it to the request objectUser.find(id,function(err,user){if(err){next(err);}elseif(user){req.user=user;next();}else{next(newError('failed to load user'));}});});
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
varapp=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...});
//index.jsapp.get('/viewdirectory',require('./mymiddleware.js'))//mymiddleware.jsmodule.exports=function(req,res){res.send('The views directory is '+req.app.get('views'));});
vargreet=express.Router();greet.get('/jp',function(req,res){console.log(req.baseUrl);// /greetres.send('Konichiwa!');});app.use('/greet',greet);// load the router on '/greet'
varapp=require('express')();varbodyParser=require('body-parser');varmulter=require('multer');// v1.0.5varupload=multer();// for parsing multipart/form-dataapp.use(bodyParser.json());// for parsing application/jsonapp.use(bodyParser.urlencoded({extended: true}));// for parsing application/x-www-form-urlencodedapp.post('/profile',upload.array(),function(req,res,next){console.log(req.body);res.json(req.body);});
// parse header from requestvarrange=req.range(1000)// the type of the rangeif(range.type==='bytes'){// the rangesrange.forEach(function(r){// do something with r.start and r.end})}
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.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 406res.status(406).send('Not Acceptable');}});
// send the rendered view to the clientres.render('index');// if a callback is specified, the rendered HTML string has to be sent explicitlyres.render('index',function(err,html){res.send(html);});// pass a local variable to the viewres.render('user',{name: 'Tobi'},function(err,html){// ...});
res.send([body])
发送Http响应,
body参数可以是Buffer object, a String, an object, or an Array.
如:
res.send(newBuffer('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'});
app.get('/user/:uid/photos/:file',function(req,res){varuid=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.");}});});
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')
如果指定了不受支持的状态码,该状态码依旧会被指定,响应信息会是该状态码的字符串表示。
res.sendStatus(2000);// equivalent to res.status(2000).send('2000')
// invoked for any requests passed to this routerrouter.use(function(req,res,next){// .. some logic here .. like any other middlewarenext();});// 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);
你同样可以使用正则表达式来进行匹配,这在你有特殊匹配时非常有用,比如说下面的路由将匹配GET /commits/71dbb9c和 GET /commits/71dbb9c..4c084f9
router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/,function(req,res){varfrom=req.params[0];varto=req.params[1]||'HEAD';res.send('commit range '+from+'..'+to);});
app.param('user',function(req,res,next,id){// try to get the user details from the User model and attach it to the request objectUser.find(id,function(err,user){if(err){next(err);}elseif(user){req.user=user;next();}else{next(newError('failed to load user'));}});});
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
varrouter=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 userreq.user.name=req.params.name;// save user ... etcres.json(req.user);}).post(function(req,res,next){next(newError('not implemented'));}).delete(function(req,res,next){next(newError('not implemented'));});
varexpress=require('express');varapp=express();varrouter=express.Router();// simple logger for this router's requests// all requests to this router will first hit this middlewarerouter.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 pointrouter.use('/bar',function(req,res,next){// ... maybe some additional /bar logging ...next();});// always invokedrouter.use(function(req,res,next){res.send('Hello World');});app.use('/foo',router);app.listen(3000);
Express4.x api 翻译(draft)
API 原文地址
express()
用以生成一个
Express
应用,express()
函数是从express
模块导出的顶级函数。方法
express.json([options])
这是Express提供的一个内置中间件函数,它基于body-parser用以解析传入的请求为JSON格式。
本函数返回只解析JSON的中间件,并且只作用于
Content-Type
请求头与type
选项匹配的请求。此解析器可接收任何编码格式的body
,支持自动解压gzip
和压缩deflate
编码。在进过此中间件处理后,
request
对象中会添加body
属性(如req.body
),它是一个对象,其中包含解析而来的数据,如果请求中没有body
可供解析或Content-Type
不匹配抑或发生了错误,body
则会是一个空对象({})
。下表描述了可选的
options
对象的属性:inflate
false
时,压缩请求体的请求会被拒绝true
limit
reviver
reviver
选项会直接传递给JSON.parse
做为第二个参数,可以在mdn上查看更多信息strict
JSON.parse
可处理的类型true
type
type-is
库进行处理,该值还可以是一个拓展名(如json
),mime type
(如application/json
)或者包含通配符的mime type
(如*/*
或者*/json
),如果是一个函数,type
类型将通过fn(req)
调用,如果返回的是一个有效值,请求会被解析verify
verify(req, res, buf, encoding)
形式被调用,其中buf
是由原始请求体构成的Buffer
,encoding
是请求的编码,解析可以通过抛出错误而放弃undefined
express.static(root,[options])
这也是Express内置中间件之一,它基于serve-static构建,用于提供静态文件。
root
参数指定提供静态文件的根目录。服务器将拼合req.url
和所提供的根目录来查找静态文件。如果没有找到对应的文件,服务器不会返回404,而将调用next()
以执行下一个中间件,允许堆叠和回退。下表描述了可选的
options
对象中可配置的属性:dotfiles
etag
etag
,express.static
始终生成弱校验Etagsextensions
['html','htm']
fallthrough
immutable
Cache-Control
响应头中启用或禁用不可变的指令。如果启用,还应指定maxAge选项以启用缓存。不可变的指令将阻止受支持的客户端在maxAge有效期间发出检查文件是否已更改的条件请求。index
lastModified
Last-Modified
头部信息设置为文件在该系统上的最后修改日期maxAge
Cache-Control
头部信息的max-age
属性,或以ms格式设置字符串redirect
setHeaders
更多信息可查看Serving static files in Express和Using middleware - Built-in middleware.
dotfiles
此选项的可选值有以下几个:
allow
:不会特别对待以点开头的文件;deny
:拒绝返回以点开头的文件,会返回403错误并调用next()
ignore
:忽略对以点开头的文件的请求,返回404错误并调用next()
fallthrough
当此选项设置为
true
,诸如无效请求或请求不存在的文件时将引起中间件调用next()
,使得下一个中间件位于栈中。设置为false
时,这些错误将触发next(err)
。将此选项设置为
true
,可以让你映射多个物理目录到相同的Web地址或者调用路由来充填不存在的文件。如果你想让某路径严格限制在某文件系统中则可以使用
false
,通过404
短路可以减小服务器压力,如果您将此中间件安装在严格意义上为单个文件系统目录的路径上,则可以使用false,这样可以使404短路,从而减少开销,这个中间件对所有的请求方法生效。
setHeaders
此选项用于指定一个函数用以自定义相应头,必须使用同步方法修改头部内容。函数签名如下:
各选项意义如下:
res
,响应对象path
,发送的文件的路径stat
,发送的文件的stat
对象express.static
使用示例express.Router([options])
创建一个新的router对象
可选参数
option
对象中的属性如下caseSensitive
/Foo
和foo
是一样的mergeParams
req.params
值,如果相互冲突,取子路由中的值false
strict
/foo
和/foo/
的响应一致你可以像对待
express
应用一样,给router添加中间件和各种方法。express.urlencoded([options])
这是Express提供的一个内置中间件,它基于body-parser解析传入的请求为
urlencoded
格式。返回只解析urlencoded的中间件,而且只解析请求头的
Content-Type
与type
匹配的请求。此解析器只接收UTF-8
编码格式的body
,支持自动解压gzip
和压缩编码。进过此中间件处理后,会返回
response
对象中将包含body
对象(如req.body
)其中包含解析所得数据,如果没有body
可供解析或Content-Type
不匹配或发生错误则会返回一个空对象({})
。对象的值可以是字符串或者数组(当extended为false时),或者其它任意类型(当extended为true时)。下表描述了可选的
options
对象中可配置的属性:extended
querystring
库(false
时)还是qs
库(true
时)来解析URL-encoded
数据。“extended”语法允许将对象和数组编码为URL格式,从而达到使用URL编码的类似获得类似JSON的体验。查看qs了解更多信息inflate
limit
parameterLimit
type
type-is
库,值可以是一个拓展名(如urlencoded
),mime type
(如"application/x-www-form-urlencoded"
)或者包含通配符的mime type
(如*/*
或者*/json
),如果是一个函数,type
类型将通过fn(req)
调用并且如果返回一个真值请求会被解析verify
verify(req, res, buf, encoding)
形式被调用,其中buf
是由原始请求体构成的Buffer
,encoding
是请求的编码,解析可以通过抛出错误而放弃undefined
Application
app
对象常被用来表示Express应用,它通过调用Express模块提供的顶级函数express()
生成app
对象具备以下方法:http
请求路径注册处理函数,可查看app.METHOD
和app.param
;app对象还提供一些其它的影响应用行为的配置,可以查看Application settings了解更多信息。
属性
app.locals
app.locals
是一个对象,其以app内部的各变量为属性一旦设置,
app.locals
属性将在整个应用的生命周期内有效,相比而言res.locals
的属性值则只在某请求的生命周期内有效。你可以在app渲染的模板的过程中访问本地变量。这样就可以为模板提供辅助函数及app级别的数据,app本地变量在中间件中可以通过
req.app.locals
访问(详见req.app
)app.mountpath
app.mountpath
属性用以表示某sub-app
所匹配的一个或多个路径模式。它和
req
对象提供的baseUrl
功能类似,不同之处在于req.baseUrl
返回的是匹配的URL路径而非匹配模式。如果一个
sub-app
有多种路径匹配模式,sub-app.mountpath
将返回一个模式的列表Events
app.on('mount',callback(parent))
mount
事件在sub-app
挂载(mount)到父app时触发,父app会当做参数传入回调函数中。Methods
app.all(path,callback[,callback])
此方法类似标准的
app.MEYHOD()
方法,不同的地方在于它将匹配所有类型的http
请求。参数
参数1:
path
默认值:/
(root path)描述:
参数2:
callback
默认值:None
描述:
示例
以下回调将响应
GET
,POST
,PUT
,DELETE
或任何其他HTTP请求方法对路由/secret
的请求:app.all()
方法在处理对某特定的前缀或匹配的特殊路径的所有类型的请求时特别有用。比如说如果你把下述代码放在所有其它路径的定义之前,就会让从此代码之后的所有路由都需要身份验证,并自动加载一个user。这些回调也不必做为终点,loadUser
可以用来执行某个任务,然后调用next()
来继续匹配之后的路由。上述代码也等同于
下面还有另外一个非常有用的
app.all
使用示例,此例和上面的例子类似,但是严格限制路径以/api
开头app.delete(path, callback [, callback ...])
为某路径的
HTTP DELETE
请求绑定特定的回调函数。更多信息可查看路由指南。参数
参数1:
path
默认值:/
(root path)描述:
参数2:
callback
默认值:None
描述:
示例
app.disable(name)
设置
setting
中的布尔值属性name
的值为false
,name
是app settings表中的值为布尔型的项。调用app.set('foo',false)
和调用app.disable('foo')
的效果一致:如:
app.disabled(name)
判断
setting
中的设置项name
的值是否为false
,如果setting
中的设置项name
的值为false
则返回true
,name
是app settings表中的值为布尔型的项。app.enable(name)
设置
setting
中的布尔值设置项name
为true
,调用app.enable('foo')
和调用app.set('foo',true)
效果相同。app.enabled(name)
判断
setting
中的设置项name
的值是否为true
,如果setting
中的设置项name
的值为true
则返回true
,name
是app settings表中的值为布尔型的项。app.engine(ext,callback)
注册
ext
格式的模板的回调函数为callback
。默认情况下,Express会基于拓展名
require()
引擎,比如说,如果你渲染文件foo.pug
,Express将在内部触发以下代码,并会为接下来的请求缓存require()
以提高性能。对不提供直接可用的
.__express
的引擎,或者你想把不同的后缀映射到当前引擎可以使用下述方法,在上面的例子中,
renderFile()
方法提供了Express
想要的相同的签名(path
,options
,callback
),不过请注意这个方法会自动在内部调用ejx.__express)
所以如果你想要渲染的文件的后缀是.ejx
,则不需要调用做别的事情。也有一些模板引擎不遵循这个约定,consolidate.js库可以映射 Node 模板引擎为准守这种规律,所以他们可以和Express无缝链接使用。
app.get(name)
返回app setting 中相关属性
name
的值,如:app.get(path,callback[,callback])
使用特定的回调函数处理特定路径的
HTTP GET
请求参数
参数1:
path
默认值:/
(root path)描述:
参数2:
callback
默认值:None
描述:
更多信息可参考routing 指南
app.listen(path,[callback])
启动UNIX套接字并侦听指定路径上的连接。此方法等同于Node的
http.Server.listen()
方法.app.listen(port,[hostname],[backlog],[callback])
绑定并监听对指定的host和端口的连接。此方法和Node的
http.Server.listen()
方法一致。由
express()
方法返回的app
实际上是一个JavaScriptFunction
,它实际上被设计为传递给Node的HTTP servers
作为回调函数来处理请求。由于app
并没有什么继承,这使得可以非常方便使用同一套代码提供http
或https
版本的app。app.listen()
方法返回一个http.Server
对象,对于http
来说,它可以像下面这样使用app.METHOD(path,callback[,callback])
依据请求的类型处理http请求,请求类型可以是
GET,PUT,POST
等等的小写模式。因此,实际的方法是app.get()
,app.post()
,app.put()
等等。点击这里可以查看详细的路由方法清单。参数
参数1:
path
默认值:/
(root path)描述:
参数2:
callback
默认值:None
描述:
路由方法
Express下述路由方法,它们和对应的HTTP方法具有相同的名称
本
API
文档中只对常用的HTTP方法进行了描述,如app.get()
,app.post()
,app.put()
以及app.delete()
。不过上面列出的其它方法使用方法也是类似的对于无效的JavaScript变量名类型,可以使用中括号来调用,比如
app['m-search']('/', function ....
app.all
会响应针对某个特定路径的所有请求,详细可参看。更多信息可参考routing 指南
app.param([name],callback)
为路由的参数添加回调函数,其中
name
是参数名或由参数组成的数组,callback
是回调函数。回调函数的参数依次是请求对象(request),响应对象(response),下一个中间件,参数值及参数名。如果
name
是一个数组,回调函数会按照它们声明的顺序,依次注册到回调函数,此时除了此数据中的最后一项,回调函数中的next
将会触发下一个注册参数的回调函数,而对于最后一个参数,next
则会调用处理当前路由的下一个中间件,此时的处理逻辑和name
只是一个字符串一样。下面的例子实现了当
:user
存在于路由的路径中时,在req
对象中添加了req.user
以供后期路由使用:处理
Param
的回调函数对于包含它们的路由来说是本地的。因此不会被app
或者其它的路由继承。Param
回调函数会在在任何匹配了该路由的处理函数前触发,并且一个请求响应周期内只会被触发一次,即使参数匹配了多个路由也是如此。对于请求
GET /user/42
将打印以下语句:对于请求
GET /user/42/3
,下面语句将被打印app.path
返回应用程序的规范路径其是一个字符串。
对于那些特别复杂加载了特别多
app
的程序,app.path
的行为会变得很复杂,这种情况下使用req.baseUrl
来获取路径更好。app.post(path,callback[,callback])
绑定针对某特定路径的
HTTP POST
请求到特定的回调函数上。更多信息可查看路由指南。参数
参数1:
path
默认值:/
(root path)描述:
参数2:
callback
默认值:None
描述:
示例
app.put(path,callback[,callback])
绑定针对某特定路径的HTTP POST请求到特定的回调函数上。更多信息可查看路由指南。
参数
参数1:
path
默认值:/
(root path)描述:
参数2:
callback
默认值:None
描述:
示例
app.render(view,[locals],callback)
通过回调函数返回某个视图对应渲染出的
HTML
,它接收一个可选的参数,这个参数是一个对象用以像视图传送本地变量。app.render()
很像res.render()
区别在于它本身不能发送渲染后的视图给客户端。app.route(path)
返回单一路由的实例,可以链式的为不同的请求绑定不同的中间件处理函数。使用
app.route()
可以避免重复的写路由名及由此造成的输入错误。app.set(name,value)
设置
setting
中的属性name
的值为value
。前面已经提到过,调用
app.set('foo',true)
设置布尔值为true
与使用app.enable('foo')
相同,类似的,调用app.set('foo',false)
与app.disable('foo')
相同。使用
app.get
可以获取设定的值。应用设定
下表列出了
app setting
的可选项注意
sub-app
具有以下特征:settings
的值,其值必须在sub-app
中设置;例外:
case sensitive routing
/Foo
和/foo
是不同的路由,当禁用时,/Foo
和/foo
将被看做一样的,**注意:**Sub-app将继承此值N/A(undefined)
env
production
;详见 Production best practices: performance and reliability.process.env.NODE_ENV
(Node_ENV环境变量)或如果NODE_ENV
没有设置则为development
etag
Etag
响应头。可选值可参考options table,更多关于Etag可以参考 维基百科--Etagjsonp callback name
json escape
res.josn
,res.josnp
以及res.send
的JSON响应启用转义,会转义JSON中的<
,>
,&
为Unicode。此设置的目的在于当响应来自HTML的响应时协助缓解某些类型的持续XSS攻击。**注意:**sub-app将继承此值的设置N/A(undefined)
josn replacer
JSON.stringly
使用的replacer
参数 **注意:**Sub-app将继承此值在setting中的设置N/A(undefined)
json spaces
JSON.stringly
使用的space
参数,此值被用来设置用于美化缩进的空格数量,注意:Sub-app
将继承此值N/A(undefined)
query parser
false
将禁用query
解析,也可以设置其值为simple
或extended
或者一个自定义的查询字符串解析函数。 最简单的query parser是基于Node的原生query parserquerystring
,拓展的query parser基于qs
。 自定义的查询字符串解析函数将接收完整的查询字符串,并且必须返回一个有查询名和它们的值组成的对象strict routing
/foo
和/foo/
为不同的路由。否则设为相同的路由 注意: Sub-app将继承此设置N/A (undefined)
subdomain offset
trust proxy
X-Forwarded-*
请求头来确定客户端的IP地址及连接,注:X-Forwarded- *
标头容易伪造,检测到的IP地址不可靠。 启用后,Express会尝试确定通过前置代理或一系列代理连接的客户端的IP地址,req.ips
属性将包含连接的客户端的IP地址组成的数组。要启用它,可以查看trust proxy options table;trust proxy
的设置使用了proxy-addr包,可以查看其文档了解更多内容。 注: 尽管包含默认值,sub-apps会继承其值false(disabled)
views
process.ced() + '/views'
view cache
NODE_ENV
设置为producetion
时为生产环节)。true
,否则为undefined
view engine
N/A(undefined)
x-powered-by
X-Powered-By:Express
HTTP 头部true
trust proxy
的可用设置值参考Express behind proxies可获取更多的信息。
Boolean
true
,客户端的IP地址将被认为是X-Forwarded- *
头中最左边的条目,如果设置为false
,后端应用被认为直接与互联网连接,并入客户端的IP
地址可以从req.connection.remoteAddress
中获取,这也是默认的设置。subnet
或者一组IP地址和一组可信任的子网的组合,下面展示了预配置的子网名称:loopback - 127.0.0.1/8, ::1/128
,linklocal - 169.254.0.0/16, fe80::/10
,uniquelocal - 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/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
etag
选项的配置Boolean
true
将允许weak Etag
,这是默认的设置,设置为false
将禁用Etag
String
strong
,将允许strong Etag
,设置为weak
,将允许weak Etag
Function
app.use([path],callback[,callback])
为指定的路径指定中间件函数,当请求的路径与之匹配时,中间件函数将会被执行。
参数
参数1:
path
默认值:/
(root path)描述:
参数2:
callback
默认值:None
描述:
描述
将会匹配任何当前路径的子路径,如
app.use('/apple',...)
将匹配/apple
,/apple/images
,/apple/images/news
等等。path
默认的值是/
,如果不设置路径,所用中间件将响应每一个请求。比如说下述中间件函数将响应每一个请求
中间件函数将会按照顺序执行,因此中间件的顺序非常重要。
错误处理中间件
错误处理中间件需要接受四个参数,使用时必须传入四个参数以证明当前中间件时错误处理中间件。这四个参数中包含
next
,即使你用不上next
,也需要在参数中包含它,这样才能满足错误处理中间件的函数签名。签名不对当前中间件会被当做普通的中间件使用而失去处理错误的能力。关于错误处理中间件的详细信息可以参考这里。除了必须接受四个参数,错误处理中间件的定义和普通中间件一样,其函数签名固定为
(err,req,res,next)
路径写法示例
下表是一些有效的路径示例
type:
path
:示例:
将匹配以
/abcd
开头的路径:type: 路径通配符
type: 正则表达式
type: 数组
中间件回调函数示例
下面的示例展示了
app.use()
,app.METHOD()
,app.all()
中中间件函数的使用方法。单个中间件
一系列的中间件
数组
组合
下面是一些在
Express App
中使用express.static中间件的示例。Request
req
对象代表的是http
请求,该对象中包含由请求而来的query
,参数,body
,HTTP headers
等解析而来的属性。按照惯例(此文档也是如此)请求对象会记为req
(HTTP
响应对象记为res
),不过这个名字具体是什么还是依据回调函数中的定义。比如:
同样,你也可以按照下面这样做:
req
对象是node本身的请求对象的增强版,并且支持所有的内置字段和方法.属性
req.app
此属性指向使用当前中间件的Express application。
如果你遵照以下模式,在一个模块中导出一个中间件然后在主文件中
require()
这个中间件,则可以在中间件中通过req.app
获取到当前的Express
实例。比如:
req.baseUrl
获取一个路由器实例所匹配的路径。
req.baseUrl
属性和app
对象的mountpath
属性类似,不同的地方在于app. mountpath
返回的是匹配的路径模式。比如:
即使你使用的是路径通配符或者一组路径模式来匹配路由,
baseUrl
属性返回的也是匹配的字符串而非模式本身,如:当请求的路径为
/greet/ip
时,req.baseUrl
的值为/greet
,当请求的路径为/hello/jp
时,req.baseUrl
为/hello
。req.body
包含从
request body
中提交而来的键值对形式的数据。默认情况下,req.body
的值为undefined
,你需要使用如body-parser
或multer
这类body解析中间件来为其填充内容。下例展示了如何使用
body
解析中间件来扩充req.body
中的内容:req.cookies
当使用
cookie-parser
中间件时,此属性是一个由请求中的cookie信息构建的对象。如果请求中没有cookie
,其值为{}
。如果cookie有签名,则需要使用
req.signedCookies
.可参照cookie-parser查看更多信息。
req.fresh
用以表征当前请求是否“新鲜”,与
req.stale
相反。如果
cache-control
请求头不是no-cache
并且下面的每一项的值都不是true
,则它的值为true
.if-modified-since
请求头是指定的,并且last-modified
请求头等于或者早于modified
响应头if-none-match
请求头为*
;if-none-match
请求头在被解析为指令后,不匹配etag
响应头更多信息可查看fresh
req.hostname
用以表征从
HTTP header
派生出来的主机名。当
trust proxy
不等于false
时,此属性将使用X-Forwarded-Host
header中的值,此值可以通过客户端或者代理设置。req.ip
用以表征请求的远程
ip
。当
trust proxy
不为false
时,此值将取自X-Forwarded-For header.
最左侧,此请求头可以被客户端或者代理设置。req.ips
当
trust proxy
不等于false
时,此属性将使用X-Forwarded-Host
header中指定的一组IP地址。或者将包含一个空数组,此请求头可以被客户端或者代理设置。比如说,如果
X-Forwarded-For
为client, proxy1, proxy2
,req.ips
将会是["client", "proxy1", "proxy2"]
,而proxy2是最下游的。req.method
包含一个对应于当前请求方法的字符串,如
GET,POST,PUT
等等。req.originalUrl
此属性非常类似于
req.url
,不同之处在于,它保留了原始请求URL,允许你为内部路由重写req.url
。比如说,可以使用app.use()
的mounting
功能来重写req.url
以去除挂载点。在中间件函数中,
req.originalUrl
是req.baseUrl
和req.path
的组合,如下所示:req.params
此属性是一个映射到命名路由参数的对象。比如你的路由为
/user/:name
,那么可以通过req.params.name
获取到name
属性的值,此对象默认值为{}
。当你的路由定义使用的是正则表达式时,可以使用
req.params[n]
来获取捕获组的值,其中n
是第n
个捕获组,此规则也适用于未命名的通配符与字符串路由(如/file/*
)的匹配:如果你需要对
req.params
中的键做改变,可以使用app.param
处理器,更改仅适用于已经在路径中定义的参数。在中间件或路由处理函数中对
req.params
对象所做的任何更改都将被重置。req.path
表示请求URL的路径部分。
req.protocol
表征请求协议的字符串,可能是
http
或https
。当
trust proxy
不等于false
时,此属性将使用X-Forwarded-Host
header中的值,此值可以通过客户端或者代理设置。req.query
此属性通过解析查询字符串而生产的对象。如果没有查询字符串,则为空对象
{}
。req.route
返回一个对象,表示当前匹配的路由,比如:
上述代码片段的输出结果如下:
req.secure
表征
TLS
连接是否建立的布尔值,等同于:req.signedCookies
当使用了cookie-parser中间件时,此属性包含请求带来的签名
cookies
,普通的cookie可通过req.cookie
访问,但是容易被伪造存在恶意攻击的风险,签名cookie实际上并不会使cookie被加密或者隐藏,但是会使得它难以被篡改(用于签名的secret
是私密的)。如果没有签名cookie,此属性的值为
{}
。更多信息可查看cookie-parser中间件。
req.stale
表征此请求是否是过时,此属性是
req.fresh
的对立面。更多信息可查看req.fresh.req.subdomains
表征请求域名的子域名构成的数组。
app settings 中
subdomain offset
的默认值为2,此值可以用来确定子域名的起始位置。可通过app.set()
来改变默认值。req.xhr
是一个布尔值,如果请求头的
X-Requested-With
为XMLHttpRequest
,则为true
,表明该请求由一个类似jQuery
的客户端库发起。Methods
req.accepts(types)
检测指定的内容类型是否被接受,结果基于HTTP中的
Accept
请求头。此方法返回最佳匹配值,如果都不匹配则返回false
,这种情况下,应用的状态码应该为406Not Acceptable
。type
的值可以是单个的MIME
类型字符串(比如说application/json
),可以是拓展名如json
,可以是由逗号分隔的列表,或者一个数组。如果是列表或者数组,则返回最佳的匹配值。查看accepts可了解更多信息。
req.acceptsCharsets(charset[,...])
返回指定的字符集中第一个匹配的字符集,此结果基于
Accept-Charset
请求头,如果指定的字符集都不被认可则返回false
.查看accepts可了解更多信息。
req.acceptsEncodings(encoding [, ...])
返回指定的编码集中的第一个匹配的编码,结果基于
Accept-Encoding
请求头,如果都不匹配则返回false
.查看accepts可了解更多信息。
req.acceptsLanguages(lang [, ...])
返回匹配到的第一种语言,结果技术
Accept-Language
请求头。如果都不匹配则返回false
.查看accepts可了解更多信息。
req.get(field)
获取请求头中对应项的值(大小写不敏感),
Referrer
和Referer
是通用的。结果和
req.header(filed)
一致。req.is(type)
如果传入请求的“Content-Type”HTTP头字段与type参数指定的MIME类型匹配,则返回匹配的内容类型。否则返回false。
可参看type-is了解更多信息。
req.param(name [, defaultValue])
req.range(size[, options])
规范 头解析器。
size
参数表示资源的最大值。options
是一个可包含如下值得对象:combine
false
,当设置为true
时,域将被合并返回就类似本身他们在header中是这样表示的一样此方法会返回一个数组代表成功或者一个负数表示错误的解析
Response
res
对象代表的是当Express app 接收 HTTP 请求时 发送的 HTTP 响应。一般说来此对象会被命名为res
(相应请求对象是req
),不过其命名实际上是由回调函数中的参数确定的。比如说你可以这样做:
也可以这样做:
res
对象是Node内置的response
对象的加强版并且支持其所有的内置方法。属性
res.app
指向使用该中间件的
express
实例,在请求对象中req.app
和res.app
一样。res.headersSent
是一个布尔值,指示
app
是否为响应发送了HTTP headers
。res.locals
表示包含在请求生命周期内的本地变量。除了在请求/响应过程中视图渲染时可用,其余和 app.locals 功能一样。
这个属性在暴露请求层面的信息时非常有用,比如 路径名, 授权用户, 用户设置等等。
方法
res.append(field[,value])
添加指定值到HTTP响应头中,如果
header
不存在,则依据指定的值创建该头,值可以是字符串或者数组。注意:在
res.append()
后面调用res.set()
将覆盖前面设置的值。res.attachment([filename])
设置HTTP响应头
Content-Disposition
为attachment
,如果指定了filename
,则会依据filename
的后缀通过res.type()
设置Content-Type
,同时会设置Content-Disposition “filename=”
部分:res.cookie(name, value [, options])
设置cookie
name
的值为value
。 value的值可以是一个字符串或者转换为json
的对象。options
参数是一个可以拥有以下属性的参数。encodeURIComponent
/
使用示例如下:
encode
值是一个函数,用于指定cookie
的编码格式,不支持异步函数。示例如下:
maxAge
是一种更为方便的设置过期时间的方法,如下:cookie的值也可以是一个对象,其之后会被
bodyParser()
序列化为JSON。当使用
cookie-parser
中间件时,此方法同样支持签名cookie,只需要设置signed
为true
,res.cookie()
就会利用传输给cookieParser(secret)
的secret对该值进行签名。之后你可以通过
req.signedCookie
读取签名的cookie值。res.clearCookie(name[,options])
清除名称为
name
的cookie。res.download(path [, filename] [, options] [, fn])
已附件在路径中传输文件,一般说来,浏览器会提示用户下载文件,默认情况下
Content-Disposition
header 中的filename=
参数就是路径(此值一般会出现在浏览器的对话框中)。使用filename
参数可用覆盖此值。传输出错或者下载完成会调用回调函数fn
。此方法使用res.sendFile()
来传送文件。可选的options参数传递给底层的
res.sendFile()
调用,并采用与其完全相同的参数。res.end([data] [, encoding])
用于结束响应过程,此方法来自node核心,
http.ServerResponse
模块中的response.end()
.用于不传输任何数据快速结束响应,如果你想要传输数据,请使用res.send()
或者res.json()
res.format(object)
如果请求对象中存在的
Accept
HTTP头,可触发内容协商,将使用req.accepts()
值的权重为选择请求对应的处理器,如果请求的Accept
请求头没有被指定,将触发第一个回调函数,当没有匹配值时,服务器会返回406 “Not Acceptable”,或者触发默认的回调函数。当回调函数被选定时,响应头的
Content-Type
将会被自动设定,当然在回调函数中你也可以使用res.set()
或者res.type()
来更改此请求头的值。下例中,当
Accept
头设置为“application/json” 或 “*/json” 时响应为{ "message": "hey" }
,(如果Accept
头设置为*/*
,响应为hey
)。除了指定规范化的
MIME
类型,还可以使用拓展名来映射,来简化上述语句:res.get(field)
依据指定的
field
,返回指定的HTTP
响应头对应的值,field
大小写不敏感。res.json([body])
发送一个JSON响应,此方法将使用正常的内容类型发送响应,参数将通过
JSON.stringify()
转换为JSON
字符串。参数可以是任何JSON类型,包括对象,数组,字符串,布尔值,数值等等,你也可以使用它转换其它值为JSON,比如说
null
,undefined
(虽然这些类型从技术上来讲不是有效的JSON)。res.jsonp([body])
使用JSONP发送JSON响应,除了支持
JSONP
回调,此方法与res.json()
相同。默认情况下,JSONP的回调函数名称为
callback
,可以通过设置jsonp callback name来更换。以下是JSONP的一些使用示例:
res.links(links)
把参数添加到HTTP 响应头
Link
中。如下例:
将得到以下结果;
res.location(path)
设置响应头
Location
为指定的值:值
back
具有特殊的含义,它指向请求头中的Referer
头的值,如果请求头中Referer
没有被指定,响应头中的Location
将指向/
。res.redirect([status,] path)
依据指定的路径和状态(一个对应于HTTP状态码的正整数)重定向URL,如果没有指定,默认值为
302 Found
。可以传入一个完整的站点信息重定向到其它的网站
重定向也可以相对域名所有的
root
发生,比如说,如果当前位置位于http://example.com/admin/post/new
,下述代码将重定向至http://example.com/admin
。重定向也可以相对于当前的URL,比如下面的例子中将从
http://example.com/blog/admin/
重定向至http://example.com/blog/admin/post/new
。如果从
http://example.com/blog/admin
重定向至post/new
将重定向至http://example.com/blog/post/new.
如果传入的值为
back
,将重定向至referer
请求头,如果referer
不存在则默认为/
。res.render(view [, locals] [, callback])
渲染视图并发送渲染得到的
html
字符串到客户端。可选参数如下:locals
:一个定义了视图函数中可用的本地变量组成的对象;callback
:一个回调函数。如果提供,该方法返回可能的错误和呈现的字符串,但不会执行自动响应。发生错误时,该方法会在内部调用next(err)
。view
参数是一个字符串,指向视图文件的位置。此值可以是决定路径也可以是相对views setting
的相对路径,如果该路径不包含拓展名则view engine
的设置会决定其拓展名,如果包含拓展名将以指定的模板引擎渲染模块(使用require
),并将触发对应模块的__express
方法来进行渲染。更多信息可见在Express中使用模板引擎。res.send([body])
发送
Http
响应,body
参数可以是Buffer object, a String, an object, or an Array.
如:
此方法为非流式响应提供了一些自动操作,如自动添加
Content-Length
响应头,并且自动添加HEAD
以及HTTP
缓存。当参数为
Buffer
对象时,此方法设置Content-Type
响应头为application/octet-stream
,除非像下面这样预先定义:当参数为
String
时,会自动设置Content-Type
为“text/html”当响应为对象或者数组时,响应值为
JSON
表示:res.sendFile(path [, options] [, fn])
基于给定的路径传输文件,并依据文件的拓展名设置响应头的
Content-Type
.除非在options
对象中设置了root
,否者路径必须为绝对路径。下表提供了
options
参数的详细信息Cache-Control
响应头中的max-age
值,可以是数值或者数值格式的字符串Last-Modified
响应头的值为该文件在系统中最后被修改的日期,设置为false 可以禁用它Cache-Control
响应头Cache-Control
的immutable
指示,如果启用,maxAge
应该指示为可用。此指示会在maxAge
生命周期内组织客户端进行额外的请求当传输完成或者出现错误时会触发回调函数
fn(err)
,如果指定了回调函数并且确实发生了错误,则回调函数必须处理响应过程,可中断响应也可传入控制到下一个route
。示例如下:
下面的例子展示了使用
res.sendFile
为服务文件提供精细的控制:更多信息可以查看send。
res.sendStatus(statusCode)
设置HTTP响应的状态码为
statusCode
,并且在响应body
中添加它的字符串表示。如果指定了不受支持的状态码,该状态码依旧会被指定,响应信息会是该状态码的字符串表示。
关于状态码的更多信息
res.set(field [, value])
设置响应头对应的
field
为value
,此方法也支持同时设置多个field
为对应的值。此方法和
res.header(field [, value]).
功能一致。res.status(code)
设置响应的HTTP状态码,它可以看做一个可链式调用的response.statusCode。
res.type(type)
设置
Content-Type
为对应的MIME
类型,如果type
中包含/
,将会设置Content-Type
为传入的type
。res.vary(field)
如果不存在添加该字段到
Vary
响应头中。Router
router
对象是一个中间件或者路由的独立实例,你可以把它当做迷你程序,只能执行中间件和路由函数。每一个Express程序都有一个内置的app
路由。路由器的行为就像中间件本身一样,所以你可以用它作为
app.use()
的参数,或者作为另一个路由器的use()
方法的参数。顶层的
express
对象拥有一个Router()
方法可以用于创建一个router
对象。一旦创建了一个路由器对象,就可以像应用程序一样向其添加中间件和HTTP方法路由(例如
get
,put
,post
等)比如:你可以为特定的路径指定路由,从而把对不同路由的处理分隔到不同的文件中。
方法
router.all(path, [callback, ...] callback)
此方法类似标准的
router.MEYHOD()
方法,不同的地方在于它将匹配所有的http
请求。app.all()
方法在处理对某特定的前缀或匹配的特殊路径的所有类型的请求时特别有用。比如说如果你把下述代码放在所有其它路径的定义之前,就会让从此代码之后的所有路由都需要身份验证,并自动加载一个user。这些回调也不必做为终点,loadUser
可以用来执行某个任务,然后调用next()
来继续匹配之后的路由。上述代码也等同于
下面还有另外一个非常好用的全局函数示例,这个例子和上面那个类似,但是严格限制路径以
/api
开头router.METHOD(path, [callback, ...] callback)
依据请求的类型处理http请求,请求类型可以是
GET,PUT,POST
等等的小写模式。因此,实际的方法是app.get()
,app.post()
,app.put()
等等。点击这里可以查看详细的路由方法清单。你也可以提供多个回调函数,他们会被同等的对待,并且像中间件一样行为,只不过这些回调可能会调用next('route')来绕过剩余的路由回调。您可以使用此机制在路由上执行预处理,并且在不再需要在继续处理时把控制权移交给下一个路由。
下面的例子展示了最简单的路由定义,Express会将路径字符串转换为正则表达式,用以匹配接收到的请求,匹配时不会考虑查询字符串,比如
GET /
将会匹配GET /?name=tobi
,如下所示:你同样可以使用正则表达式来进行匹配,这在你有特殊匹配时非常有用,比如说下面的路由将匹配
GET /commits/71dbb9c
和GET /commits/71dbb9c..4c084f9
router.param(name, callback)
为路由参数添加回调函数,其中
name
是参数名或参数组成的数组,callback
是回调函数。回调函数的参数依次是请求对象(request),响应对象(response),下一个中间件,参数值及参数名。如果
name
是一个数组,回调函数会按照它们声明的顺序被注册到其中的每个值。此外除了最后一个声明的参数,回调函数中的next
将会触发下一个注册参数的回调函数,而对于最后一个参数,next
则会调用处理当前路由的下一个中间件,此时的处理就像name
只是一个字符串一样。比如说当
:user
存在于路由的路径中时,你可能想映射用户加载逻辑以自动提供req.user
给路由或者对参数输入执行验证。Param 回调函数对于它们定义的路由来说是本地的。它们不会被载入的app及router继承。因此,定义在
app
上的参数回调只会被定义在app
路由上的路由参数触发。所有的参数回调将会在任何匹配该路由的处理函数前触发,并且在一个请求响应周期内只会被触发一次,即使参数匹配了多个路由也是如此。
对于请求
GET /user/42
将打印以下语句:对于请求
GET /user/42/3
,下面语句将被打印router.route(path)
返回单一路由的实例,你可以使用不同的可选中间件来处理不同类型的请求。使用
route.route()
可以避免重复的写路由名及由此造成的输入错误。这种方法为单一的路径
/users/:user_id
添加了不同的 HTTP 方法。router.use([path], [function, ...] function)
为可选的
path
添加一系列的处理函数,path
默认值为/
。此方法类似于
app.use()
,下面是一个简单的例子,可以查看app.use
查看更多信息。中间件就像水暖管一样,有请求时会从第一个匹配的中间件开始逐步往下到所有匹配到的中间件。
匹配的路径被剥离并且对中间件函数不可见,此特性的意义在于一个匹配的中间件函数可以独立于路径执行。
使用
router.use()
定义的中间件函数非常重要,它们会依次被触发,比如说第一个中间件函数常常是logger
,这样所有的请求都会被log
.假如现在你想忽略静态文件的
log
,但是对其它的请求还是想要有log
,你只需把express.static()
移动到logger
中间件上面即可。静态服务器是另一个很好的例子,假如你想给
/public
更高的权重,你可以按照下面这样进行:router.use()
方法还支持命名参数,以便其他路由器的挂载点可以使用命名参数进行预加载。注意:虽然这些中间件功能是通过一个特定的路由器添加的,但是当它们运行的时候是由它们所匹配的路径(而不是路由器)来定义的。因此,如果路由匹配,通过一个路由器添加的中间件可以运行其他路由器。例如,这段代码显示了两个不同的路由器匹配到了同一个路径
上面的例子中,虽然
authenticate
定义在了authRouter
上,但是也会执行openRouter
路由器关联的中间件,为了避免这种行为,最好不同的路由器不要匹配相同的路径。The text was updated successfully, but these errors were encountered: