nodejs 框架 中文express 4.xxx中文API手册

寻技术 JS脚本 / Node.Js 2023年07月11日 97
 
 介于最近express 中文文档比较难找的现状,特地找了一个,供大家学习思考

express 翻译 api文档 中文


--

 
 

express()

express()用来创建一个Express的程序。express()方法是express模块导出的顶层方法。

 
  1. var express = require('express');
  2. var app = express();
 

Methods

 

express.static(root, [options])

server-static模块为基础开发,负责托管 Express 应用内的静态资源。 
参数root为静态资源的所在的根目录。 
参数options是可选的,支持以下的属性:

属性 描述 类型 默认值
dotfiles 是否响应点文件。供选择的值有"allow","deny"和"ignore" String "ignore"
etag 使能或者关闭etag Boolean true
extensions 设置文件延期回退 Boolean true
index 发送目录索引文件。设置false将不发送。 Mixed "index.html"
lastModified 设置文件在系统中的最后修改时间到Last-Modified头部。可能的取值有falsetrue Boolean true
maxAge 在Cache-Control头部中设置max-age属性,精度为毫秒(ms)或则一段ms format的字符串 Number 0
redirect 当请求的pathname是一个目录的时候,重定向到尾随"/" Boolean true
setHeaders 当响应静态文件请求时设置headers的方法 Funtion  

Serving static files in Express。

 

Application()

app对象一般用来表示Express程序。通过调用Express模块导出的顶层的express()方法来创建它:

 
  1. var express = require('express');
  2. var app = express();
  3. app.get('/', function(req, res) {
  4. res.send('hello world!');
  5. });
  6. app.listen(3000);

app对象具有以下的方法:

  • 路由HTTP请求;具体可以看app.METHOD和app.param这两个例子。
  • 配置中间件;具体请看app.route。
  • 渲染HTML视图;具体请看app.render。
  • 注册模板引擎;具体请看app.engine。

Application settings。

 

Properties

 

app.locals

app.locals对象是一个javascript对象,它的属性就是程序本地的变量。

 
  1. app.locals.title
  2. // => 'My App'
  3. app.locals.email
  4. // => 'me@myapp.com'

一旦设定,app.locals的各属性值将贯穿程序的整个生命周期,与其相反的是res.locals,它只在这次请求的生命周期中有效。

req.app),Locals可以在中间件中使用。

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

app.mountpath

app.mountpath属性是子程序挂载的路径模式。

一个子程序是一个express的实例,其可以被用来作为路由句柄来处理请求。

 
  1. var express = require('express');
  2. var app = express(); // the main app
  3. var admin = express(); // the sub app
  4. admin.get('/', function(req, res) {
  5. console.log(admin.mountpath); // /admin
  6. res.send('Admin Homepage');
  7. });
  8. app.use('/admin', admin); // mount the sub app

baseUrl属性比较相似,除了req.baseUrl是匹配的URL路径,而不是匹配的模式。如果一个子程序被挂载在多条路径模式,app.mountpath就是一个关于挂载路径模式项的列表,如下面例子所示。

 
  1. var admin = express();
  2. admin.get('/', function(req, res) {
  3. console.log(admin.mountpath); // ['adm*n', '/manager']
  4. res.send('Admin Homepage');
  5. });
  6. var secret = express();
  7. secret.get('/', function(req, res) {
  8. console.log(secret.mountpath); // /secr*t
  9. res.send('Admin secret');
  10. });
  11. admin.use('/secr*t', secret); // load the 'secret' router on '/secr*t', on the 'admin' sub app
  12. app.use(['/adm*n', '/manager'], admin); // load the 'admin' router on '/adm*n' and '/manager' , on the parent app
 

Events

 

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

当子程序被挂载到父程序时,mount事件被发射。父程序对象作为参数,传递给回调方法。

 
  1. var admin = express();
  2. admin.on('mount', function(parent) {
  3. console.log('Admin Mounted');
  4. console.log(parent); // refers to the parent app
  5. });
  6. admin.get('/', function(req, res) {
  7. res.send('Admin Homepage');
  8. });
  9. app.use('/admin', admin);
 

Methods

 

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

app.all方法和标准的app.METHOD()方法相似,除了它匹配所有的HTTP动词。 
对于给一个特殊前缀映射一个全局的逻辑处理,或者无条件匹配,它是很有效的。例如,如果你把下面内容放在所有其他的路由定义的前面,它要求所有从这个点开始的路由需要认证和自动加载一个用户。记住这些回调并不是一定是终点:loadUser可以在完成了一个任务后,调用next()方法来继续匹配随后的路由。

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

或者这种相等的形式:

 
  1. app.all('*', requireAuthentication);
  2. app.all('*', loadUser);

另一个例子是全局的白名单方法。这个例子和前面的很像,然而它只是限制以/api开头的路径。

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

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

routing guide。 
你可以提供多个回调函数,它们的行为和中间件一样,除了这些回调可以通过调用next('router')来绕过剩余的路由回调。你可以使用这个机制来为一个路由设置一些前提条件,如果不能满足当前路由的处理条件,那么你可以传递控制到随后的路由。

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

app.disable(name)

app settings table中各属性的一个。调用app.set('foo', false)和调用app.disable('foo')是等价的。 
比如:

 
  1. app.disable('trust proxy');
  2. app.get('trust proxy');
  3. // => false
 

app.disabled(name)

app settings table中各属性的一个。

 
  1. app.disabled('trust proxy');
  2. // => true
  3. app.enable('trust proxy');
  4. app.disabled('trust proxy');
  5. // => false
 

app.enable(name)

app settings table中各属性的一个。调用app.set('foo', true)和调用app.enable('foo')是等价的。

 
  1. app.enable('trust proxy');
  2. app.get('trust proxy');
  3. // => true
 

app.enabled(name)

app settings table中各属性的一个。

 
  1. app.enabled('trust proxy');
  2. // => false
  3. app.enable('trust proxy');
  4. app.enabled('trust proxy');
  5. // => true
 

app.engine(ext, callback)

注册给定引擎的回调,用来渲染处理ext文件。 
默认情况下,Express需要使用require()来加载基于文件扩展的引擎。例如,如果你尝试渲染一个foo.jade文件,Express在内部调用下面的内容,同时缓存require()结果供随后的调用,来加速性能。

 
  1. app.engine('jade', require('jade').__express);

使用下面的方法对于那些没有提供开箱即用的.__express方法的模板,或者你希望使用不同的模板引擎扩展。 
比如,使用EJS模板引擎来渲染.html文件:

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

consolidate.js库映射模板引擎以下面的使用方式,所以他们可以无缝的和Express工作。

 
  1. var engines = require('consolidate');
  2. app.engine('haml', engines.haml);
  3. app.engine('html', engines.hogan);
 

app.get(name)

app settings table中各属性的一个。 
如下:

 
  1. app.get('title');
  2. // => undefined
  3. app.set('title', 'My Site');
  4. app.get('title');
  5. // => 'My Site'
 

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

routing guide。 
你可以提供多个回调函数,它们的行为和中间件一样,除了这些回调可以通过调用next('router')来绕过剩余的路由回调。你可以使用这个机制来为一个路由设置一些前提条件,如果请求没能满足当前路由的处理条件,那么传递控制到随后的路由。

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

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

http.Server.listen()是一样的。

 
  1. var express = require('express');
  2. var app = express();
  3. app.listen(3000);

通过调用express()返回得到的app实际上是一个JavaScript的Function,被设计用来作为一个回调传递给Node HTTP servers来处理请求。这样,其就可以很简便的基于同一份代码提供http和https版本,所以app没有从这些继承(它只是一个简单的回调)。

 
  1. var express = require('express');
  2. var https = require('https');
  3. var http = require('http');
  4. http.createServer(app).listen(80);
  5. https.createServer(options, app).listen(443);

app.listen()方法是下面所示的一个便利的方法(只针对HTTP协议):

 
  1. app.listen = function() {
  2. var server = http.createServer(this);
  3. return server.listen.apply(server, arguments);
  4. };
 

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

routing guide。 
Express支持下面的路由方法,对应与同名的HTTP方法:

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

如果使用上述方法时,导致了无效的javascript的变量名,可以使用中括号符号,比如,app['m-search']('/', function ...

你可以提供多个回调函数,它们的行为和中间件一样,除了这些回调可以通过调用next('router')来绕过剩余的路由回调。你可以使用这个机制来为一个路由设置一些前提条件,如果请求没有满足当前路由的处理条件,那么传递控制到随后的路由。

本API文档把使用比较多的HTTP方法app.get()app.postapp.put()app.delete()作为一个个单独的项进行说明。然而,其他上述列出的方法以完全相同的方式工作。

app.all()是一个特殊的路由方法,它不属于HTTP协议中的规定的方法。它为一个路径加载中间件,其对所有的请求方法都有效。

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

app.param([name], callback)

给路由参数添加回调触发器,这里的name是参数名或者参数数组,function是回调方法。回调方法的参数按序是请求对象,响应对象,下个中间件,参数值和参数名。 
如果name是数组,会按照各个参数在数组中被声明的顺序将回调触发器注册下来。还有,对于除了最后一个参数的其他参数,在他们的回调中调用next()来调用下个声明参数的回调。对于最后一个参数,在回调中调用next()将调用位于当前处理路由中的下一个中间件,如果name只是一个string那就和它是一样的(就是说只有一个参数,那么就是最后一个参数,和数组中最后一个参数是一样的)。 
例如,当:user出现在路由路径中,你可以映射用户加载的逻辑处理来自动提供req.user给这个路由,或者对输入的参数进行验证。

 
  1. app.param('user', function(req, res, next, id) {
  2. User.find(id, function(error, user) {
  3. if (err) {
  4. next(err);
  5. }
  6. else if (user){
  7. req.user = user;
  8. } else {
  9. next(new Error('failed to load user'));
  10. }
  11. });
  12. });

对于Param的回调定义的路由来说,他们是局部的。它们不会被挂载的app或者路由继承。所以,定义在app上的Param回调只有是在app上的路由具有这个路由参数时才起作用。 
在定义param的路由上,param回调都是第一个被调用的,它们在一个请求-响应循环中都会被调用一次并且只有一次,即使多个路由都匹配,如下面的例子:

 
  1. app.param('id', function(req, res, next, id) {
  2. console.log('CALLED ONLY ONCE');
  3. next();
  4. });
  5. app.get('/user/:id', function(req, res, next) {
  6. console.log('although this matches');
  7. next();
  8. });
  9. app.get('/user/:id', function(req, res) {
  10. console.log('and this mathces too');
  11. res.end();
  12. });

GET /user/42,得到下面的结果:

 
  1. CALLED ONLY ONCE
  2. although this matches
  3. and this matches too
 
  1. app.param(['id', 'page'], function(req, res, next, value) {
  2. console.log('CALLED ONLY ONCE with', value);
  3. next();
  4. });
  5. app.get('/user/:id/:page', function(req. res, next) {
  6. console.log('although this matches');
  7. next();
  8. });
  9. app.get('/user/:id/:page', function (req, res, next) {
  10. console.log('and this matches too');
  11. res.end();
  12. });

当执行GET /user/42/3,结果如下:

 
  1. CALLED ONLY ONCE with
  2. CALLED ONLY ONCE with
  3. although this matches
  4. and this mathes too

下面章节描述的app.param(callback)在v4.11.0之后被弃用。

通过只传递一个回调参数给app.param(name, callback)方法,app.param(naem, callback)方法的行为将被完全改变。这个回调参数是关于app.param(name, callback)该具有怎样的行为的一个自定义方法,这个方法必须接受两个参数并且返回一个中间件。 
这个回调的第一个参数就是需要捕获的url的参数名,第二个参数可以是任一的JavaScript对象,其可能在实现返回一个中间件时被使用。 
这个回调方法返回的中间件决定了当URL中包含这个参数时所采取的行为。 
在下面的例子中,app.param(name, callback)参数签名被修改成了app.param(name, accessId)。替换接受一个参数名和回调,app.param()现在接受一个参数名和一个数字。

 
  1. var express = require('express');
  2. var app = express();
  3. app.param(function(param, option){
  4. return function(req, res, next, val) {
  5. if (val == option) {
  6. next();
  7. }
  8. else {
  9. res.sendStatus(403);
  10. }
  11. }
  12. });
  13. app.param('id', 1337);
  14. app.get('/user/:id', function(req, res) {
  15. res.send('Ok');
  16. });
  17. app.listen(3000, function() {
  18. console.log('Ready');
  19. });

在这个例子中,app.param(name, callback)参数签名保持和原来一样,但是替换成了一个中间件,定义了一个自定义的数据类型检测方法来检测user id的类型正确性。

 
  1. app.param(function(param, validator) {
  2. return function(req, res, next, val) {
  3. if (validator(val)) {
  4. next();
  5. }
  6. else {
  7. res.sendStatus(403);
  8. }
  9. }
  10. });
  11. app.param('id', function(candidate) {
  12. return !isNaN(parseFloat(candidate)) && isFinite(candidate);
  13. });

在使用正则表达式来,不要使用.。例如,你不能使用/user-.+/来捕获user-gami,用使用[\\s\\S]或者[\\w\\>W]来代替(正如/user-[\\s\\S]+/)。

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

app.path()

通过这个方法可以得到app典型的路径,其是一个string

 
  1. var app = express()
  2. , blog = express()
  3. , blogAdmin = express();
  4. app.use('/blog', blog);
  5. app.use('/admin', blogAdmin);
  6. console.log(app.path()); // ''
  7. console.log(blog.path()); // '/blog'
  8. console.log(blogAdmin.path()); // '/blog/admin'

如果app挂载很复杂下,那么这个方法的行为也会很复杂:一种更好用的方式是使用req.baseUrl来获得这个app的典型路径。

 

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

routing guide。 
你可以提供多个回调函数,它们的行为和中间件一样,除了这些回调可以通过调用next('router')来绕过剩余的路由回调。你可以使用这个机制来为一个路由设置一些前提条件,如果请求没能满足当前路由的处理条件,那么传递控制到随后的路由。

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

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

routing guide。 
你可以提供多个回调函数,它们的行为和中间件一样,除了这些回调可以通过调用next('router')来绕过剩余的路由回调。你可以使用这个机制来为一个路由设置一些前提条件,如果请求没能满足当前路由的处理条件,那么传递控制到随后的路由。

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

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

通过callback回调返回一个view渲染之后得到的HTML文本。它可以接受一个可选的参数,可选参数包含了这个view需要用到的本地数据。这个方法类似于res.render(),除了它不能把渲染得到的HTML文本发送给客户端。

app.render()当作是可以生成渲染视图字符串的工具方法。在res.render()内部,就是使用的app.render()来渲染视图。

如果使能了视图缓存,那么本地变量缓存就会保留。如果你想在开发的过程中缓存视图,设置它为true。在生产环境中,视图缓存默认是打开的。

 
  1. app.render('email', function(err, html) {
  2. // ...
  3. });
  4. app.render('email', {name:'Tobi'}, function(err, html) {
  5. // ...
  6. });
 

app.route(path)

返回一个单例模式的路由的实例,之后你可以在其上施加各种HTTP动作的中间件。使用app.route()来避免重复路由名字(因此错字错误)--说的意思应该是使用app.router()这个单例方法来避免同一个路径多个路由实例。

 
  1. var app = express();
  2. app.route('/events')
  3. .all(function(req, res, next) {
  4. // runs for all HTTP verbs first
  5. // think of it as route specific middleware!
  6. })
  7. .get(function(req, res, next) {
  8. res.json(...);
  9. })
  10. .post(function(req, res, next) {
  11. // maybe add a new event...
  12. })
 

app.set(name, value)

app settings table中属性的一项。 
对于一个类型是布尔型的属性调用app.set('foo', ture)等价于调用app.enable('foo')。同样的,调用app.set('foo', false)等价于调用app.disable('foo')。 
可以使用app.get()来取得设置的值:

 
  1. app.set('title', 'My Site');
  2. app.get('title'); // 'My Site'

Application Settings 
如果name是程序设置之一,它将影响到程序的行为。下边列出了程序中的设置。

Property Type Value Default
case sensitive routing Boolean 启用区分大小写。 不启用。对/Foo/foo处理是一样。
env String 环境模型。 process.env.NODE_ENV(NODE_ENV环境变量)或者"development"
etag Varied 设置ETag响应头。可取的值,可以查阅etag options table。更多关于HTTP ETag header。 weak
jsonp callback name String 指定默认JSONP回调的名称。 ?callback=
json replacer String JSON替代品回调 null
json spaces Number 当设置了这个值后,发送缩进空格美化过的JSON字符串。 Disabled
query parser Varied 设置值为false来禁用query parser,或者设置simple,extended,也可以自己实现query string解析函数。simple基于Node原生的query解析,querystring。 "extend"
strict routing Boolean 启用严格的路由。 不启用。对/foo/foo/的路由处理是一样。
subdomain offset Number 用来删除访问子域的主机点分部分的个数 2
trust proxy Varied 指示app在一个反向代理的后面,使用x-Forwarded-*来确定连接和客户端的IP地址。注意:X-Forwarded-*头部很容易被欺骗,所有检测客户端的IP地址是靠不住的。trust proxy默认不启用。当启用时,Express尝试通过前端代理或者一系列代理来获取已连接的客户端IP地址。req.ips属性包含了已连接客户端IP地址的一个数组。为了启动它,需要设置在下面trust proxy options table中定义的值。trust proxy的设置实现使用了proxy-addr包。如果想获得更多的信息,可以查阅它的文档 Disable
views String or Array view所在的目录或者目录数组。如果是一个数组,将按在数组中的顺序来查找view process.cwd() + '/views'
view cache Boolean 启用视图模板编译缓存。 在生成环境默认开启。
view engine String 省略时,默认的引擎被扩展使用。  
x-powered-by Boolean 启用X-Powered-By:ExpressHTTP头部 true

Express behind proxies来获取更多信息。

Type Value
Boolean

如果为true,客户端的IP地址作为X-Forwarded-*头部的最左边的条目。如果为false,可以理解为app直接与英特网直连,客户端的IP地址衍生自req.connection.remoteAddressfalse是默认设置。

IP addresses

一个IP地址,子网,或者一组IP地址,和委托子网。下面列出的是一个预先配置的子网名列表。

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

使用下面方法中的任何一种来设置IP地址:

app.set('trust proxy', 'loopback') // specify a single subnet
  app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address
  app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV
  app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array

当指定IP地址之后, 这个IP地址或子网会被设置了这个IP地址或子网的`app`排除在外, 最靠近程序服务的没有委托的地址将被看做客户端IP地址。

Number

信任从反向代理到app中间小于等于n跳的连接为客户端。

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

etag包。如果你需要获得更多的信息,你可以查阅它的文档。

Type Value
Boolean

设置为true,启用weak ETag。这个是默认设置。设置false,禁用所有的ETag。

String 如果是strong,使能strong ETag。如果是weak,启用weak ETag。
Function

客户自定义`ETag`方法的实现. 如果你使用这个,请确保你自己知道你在干什么。

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

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

一个路由将匹配任何路径如果这个路径以这个路由设置路径后紧跟着"/"。比如:app.use('/appale', ...)将匹配"/apple","/apple/images","/apple/images/news"等。

中间件中的req.originalUrlreq.baseUrlreq.path的组合,如下面的例子所示。

  1. app.use('/admin', function(req, res, next) {
  2. // GET 'http://www.example.com/admin/new'
  3. console.log(req.originalUrl); // '/admin/new'
  4. console.log(req.baseUrl); // '/admin'
  5. console.log(req.path);// '/new'
  6. });

在一个路径上挂载一个中间件之后,每当请求的路径的前缀部分匹配了这个路由路径,那么这个中间件就会被执行。 
由于默认的路径为/,中间件挂载没有指定路径,那么对于每个请求,这个中间件都会被执行。

 
  1. // this middleware will be executed for every request to the app.
  2. app.use(function(req, res, next) {
  3. console.log('Time: %d', Date.now());
  4. next();
  5. });

中间件方法是顺序处理的,所以中间件包含的顺序是很重要的。

 
  1. // this middleware will not allow the request to go beyond it
  2. app.use(function(req, res, next) {
  3. res.send('Hello World');
  4. });
  5. // this middleware will never reach this route
  6. app.use('/', function(req, res) {
  7. res.send('Welcome');
  8. });

路径可以是代表路径的一串字符,一个路径模式,一个匹配路径的正则表达式,或者他们的一组集合。

下面是路径的简单的例子。

Type Example
Path
// will match paths starting with /abcd
app.use('/abcd', function (req, res, next) {
  next();
})
Path Pattern
// will match paths starting with /abcd and /abd
app.use('/abc?d', function (req, res, next) {
  next();
})

// will match paths starting with /abcd, /abbcd, /abbbbbcd and so on
app.use('/ab+cd', function (req, res, next) {
  next();
})

// will match paths starting with /abcd, /abxcd, /abFOOcd, /abbArcd and so on
app.use('/ab\*cd', function (req, res, next) {
  next();
})

// will match paths starting with /ad and /abcd
app.use('/a(bc)?d', function (req, res, next) {
  next();
})
Regular Expression
// will match paths starting with /abc and /xyz
app.use(/\/abc|\/xyz/, function (req, res, next) {
  next();
})
Array
// will match paths starting with /abcd, /xyza, /lmn, and /pqr
app.use(['/abcd', '/xyza', /\/lmn|\/pqr/], function (req, res, next) {
  next();
})

方法可以是一个中间件方法,一系列中间件方法,一组中间件方法或者他们的集合。由于routerapp实现了中间件接口,你可以像使用其他任一中间件方法那样使用它们。

Usage Example
单个中间件 你可以局部定义和挂载一个中间件。
app.use(function (req, res, next) {
  next();
})
一个router是有效的中间件。
var router = express.Router();
router.get('/', function (req, res, next) {
  next();
})
app.use(router);
一个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]);
组合 你可以组合下面的所有方法来挂载中间件。
function mw1(req, res, next) { next(); }
function 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中间件。 
为程序托管位于程序目录下的public目录下的静态资源:

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

/static路径下挂载中间件来提供静态资源托管服务,只当请求是以/static为前缀的时候。

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

通过在设置静态资源中间件之后加载日志中间件来关闭静态资源请求的日志。

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

托管静态资源从不同的路径,但./public路径比其他更容易被匹配:

 
  1. app.use(express.static(__dirname + '/public'));
  2. app.use(express.static(__dirname + '/files'));
  3. app.use(express.static(__dirname + '/uploads'));
 

Request

req对象代表了一个HTTP请求,其具有一些属性来保存请求中的一些数据,比如query stringparametersbodyHTTP headers等等。在本文档中,按照惯例,这个对象总是简称为req(http响应简称为res),但是它们实际的名字由这个回调方法在那里使用时的参数决定。 
如下例子:

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

其实你也可以这样写:

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

Properties

Express 4中,req.files默认在req对象中不再是可用的。为了通过req.files对象来获得上传的文件,你可以使用一个multipart-handling(多种处理的工具集)中间件,比如busboymulterformidablemultipratyconnect-multiparty或者pez

 

req.app

这个属性持有express程序实例的一个引用,其可以作为中间件使用。 
如果你按照这个模式,你创建一个模块导出一个中间件,这个中间件只在你的主文件中require()它,那么这个中间件可以通过req.app来获取express的实例。 
例如:

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

req.baseUrl

一个路由实例挂载的Url路径。

 
  1. var greet = express.Router();
  2. greet.get('/jp', function(req, res) {
  3. console.log(req.baseUrl); // greet
  4. res.send('Konichiwa!');
  5. });
  6. app.use('/greet', greet);

即使你使用的路径模式或者一系列路径模式来加载路由,baseUrl属性返回匹配的字符串,而不是路由模式。下面的例子,greet路由被加载在两个路径模式上。

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

mountpath属性相似,除了app.mountpath返回的是路径匹配模式。

 

req.body

在请求的body中保存的是提交的一对对键值数据。默认情况下,它是undefined,当你使用比如body-parsermulter这类解析body数据的中间件时,它是填充的。 
下面的例子,给你展示了怎么使用body-parser中间件来填充req.body

 
  1. var app = require('express');
  2. var bodyParser = require('body-parser');
  3. var multer = require('multer');// v1.0.5
  4. var upload = multer(); // for parsing multipart/form-data
  5. app.use(bodyParser.json()); // for parsing application/json
  6. app.use(bodyParser.urlencoded({extended:true})); // for parsing application/x-www-form-urlencoded
  7. app.post('/profile', upload.array(), function(req, res, next) {
  8. console.log(req.body);
  9. res.json(req.body);
  10. });
 

req.cookies

当使用cookie-parser中间件的时候,这个属性是一个对象,其包含了请求发送过来的cookies。如果请求没有带cookies,那么其值为{}

 
  1. // Cookie: name=tj
  2. req.cookies.name
  3. // => "tj"

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响应头(完全不知道什么鬼)。
 
  1. req.fresh
  2. // => true
 

req.hostname

包含了源自HostHTTP头部的hostname。 
trust proxy设置项被设置为启用值,X-Forwarded-Host头部被使用来代替Host。这个头部可以被客户端或者代理设置。

 
  1. // Host: "example.com"
  2. req.hostname
  3. // => "example.com"
 

req.ips

,这里proxy2就是最远的下游。

 

req.originalUrl

req.url不是一个原生的Express属性,它继承自Node's http module。

这个属性很像req.url;然而,其保留了原版的请求链接,允许你自由地重定向req.url到内部路由。比如,app.use()mounting特点可以重定向req.url跳转到挂载点。

 
  1. // GET /search?q=something
  2. req.originalUrl
  3. // => "/search?q=something"
 

req.params

一个对象,其包含了一系列的属性,这些属性和在路由中命名的参数名是一一对应的。例如,如果你有/user/:name路由,name属性可作为req.params.name。这个对象默认值为{}

 
  1. // GET /user/tj
  2. req.params.name
  3. // => "tj"

当你使用正则表达式来定义路由规则,捕获组的组合一般使用req.params[n],这里的n是第几个捕获租。这个规则被施加在无名通配符匹配,比如/file/*的路由:

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

req.path

包含请求URL的部分路径。

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

当在一个中间件中被调用,挂载点不包含在req.path中。你可以查阅app.use()获得跟多的信息。

 

req.protocol

请求的协议,一般为http,当启用TLS加密,则为https。 
trust proxy设置一个启用的参数,如果存在X-Forwarded-Proto头部的话,其将被信赖和使用。这个头部可以被客户端或者代理设置。

 
  1. req.ptotocol
  2. // => "http"
 

req.query

一个对象,为每一个路由中的query string参数都分配一个属性。如果没有query string,它就是一个空对象,{}

 
  1. // GET /search?q=tobi+ferret
  2. req.query.q
  3. // => "tobi ferret"
  4. // GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
  5. req.query.order
  6. // => "desc"
  7. req.query.shoe.color
  8. // => "blue"
  9. req.query.shoe.type
  10. // => "converse"
 

req.route

当前匹配的路由,其为一串字符。比如:

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

前面片段的输出为:

 
  1. { path:"/user/:id?"
  2. stack:
  3. [
  4. { handle:[Function:userIdHandler],
  5. name:"userIdHandler",
  6. params:undefined,
  7. path:undefined,
  8. keys:[],
  9. regexp:/^\/?$/i,
  10. method:'get'
  11. }
  12. ]
  13. methods:{get:true}
  14. }
 

req.secure

一个布尔值,如果建立的是TLS的连接,那么就为true。等价与:

 
  1. 'https' == req.protocol;
 

req.signedCookies

当使用cookie-parser中间件的时候,这个属性包含的是请求发过来的签名cookies,不签名的并且为使用做好了准备(这句真不知道怎么翻译了...)。签名cookies驻留在不同的对象中来体现开发者的意图;不然,一个恶意攻击可以被施加在req.cookie值上(它是很容易被欺骗的)。记住,签名一个cookie不是把它藏起来或者加密;而是简单的防止篡改(因为签名使用的加密是私人的)。如果没有发送签名的cookie,那么这个属性默认为{}

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

cookie-parser。

 

req.stale

req.fresh。

 
  1. req.stale
  2. // => true
 

req.subdomains

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

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

req.xhr

一个布尔值,如果X-Requested-With的值为XMLHttpRequest,那么其为true,其指示这个请求是被一个客服端库发送,比如jQuery

 
  1. req.xhr
  2. // => true
 

Methods

 

req.accepts(types)

type值可以是一个单的MIME type字符串(比如application/json),一个扩展名比如json,一个逗号分隔的列表,或者一个数组。对于一个列表或者数组,这个方法返回最佳项(如果有的话)。

 
  1. // Accept: text/html
  2. req.accepts('html');
  3. // => "html"
  4. // Accept: text/*, application/json
  5. req.accepts('html');
  6. // => "html"
  7. req.accepts('text/html');
  8. // => "text/html"
  9. req.accepts(['json', 'text']);
  10. // => "json"
  11. req.accepts('application/json');
  12. // => "application/json"
  13. // Accept: text/*, application/json
  14. req.accepts('image/png');
  15. req.accepts('png');
  16. // => undefined
  17. // Accept: text/*;q=.5, application/json
  18. req.accepts(['html', 'json']);
  19. // => "json"

accepts。

 

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

accepts。

 

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

accepts。

 

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

accepts。

 

req.get(field)

返回指定的请求HTTP头部的域内容(不区分大小写)。ReferrerReferer的域内容可互换。

 
  1. req.get('Content-type');
  2. // => "text/plain"
  3. req.get('content-type');
  4. // => "text/plain"
  5. req.get('Something')
  6. // => undefined

其是req.header(field)的别名。

 

req.is(type)

如果进来的请求的Content-type头部域匹配参数type给定的MIME type,那么其返回true。否则返回false

 
  1. // With Content-Type: text/html; charset=utf-8
  2. req.is('html');
  3. req.is('text/html');
  4. req.is('text/*');
  5. // => true
  6. // When Content-Type is application/json
  7. req.is('json');
  8. req.is('application/json');
  9. req.is('application/*');
  10. // => true
  11. req.is('html');
  12. // => false

type-is。

 

req.param(naem, [, defaultValue])

过时的。可以在适合的情况下,使用req.paramsreq.body或者req.query

返回当前参数name的值。

 
  1. // ?name=tobi
  2. req.param('name')
  3. // => "tobi"
  4. // POST name=tobi
  5. req.param('name')
  6. // => "tobi"
  7. // /user/tobi for /user/:name
  8. req.param('name')
  9. // => "tobi"

按下面给出的顺序查找:

  • req.params
  • req.body
  • req.query

可选的,你可以指定一个defaultValue来设置一个默认值,如果这个参数在任何一个请求的对象中都不能找到。

直接通过req.paramsreq.bodyreq.query取得应该更加的清晰-除非你确定每一个对象的输入。 
Body-parser中间件必须加载,如果你使用req.param()。详细请看req.body。

 

Response

res对象代表了当一个HTTP请求到来时,Express程序返回的HTTP响应。在本文档中,按照惯例,这个对象总是简称为res(http请求简称为req),但是它们实际的名字由这个回调方法在那里使用时的参数决定。 
例如:

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

这样写也是一样的:

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

Properties

 

res.app

这个属性持有express程序实例的一个引用,其可以在中间件中使用。 
res.app和请求对象中的req.app属性是相同的。

 

res.headersSent

布尔类型的属性,指示这个响应是否已经发送HTTP头部。

 
  1. app.get('/', function(req, res) {
  2. console.log(res.headersSent); // false
  3. res.send('OK'); // send之后就发送了头部
  4. console.log(res.headersSent); // true
  5. });
 

res.locals

一个对象,其包含了响应的能够反应出请求的本地参数和因此只提供给视图渲染,在请求响应的周期内(如果有的话)--我要翻译吐了。否则,其和app.locals是一样的。(不知道翻译的什么...) 
这个参数在导出请求级别的信息是很有效的,这些信息比如请求路径,已认证的用户,用户设置等等。

 
  1. app.use(function(req, res, next) {
  2. res.locals.user = req.user;
  3. res.locals.authenticated = !req.user.anonymous;
  4. next();
  5. });
 

Methods

 

res.append(field [, value])

res.append()方法在Expresxs4.11.0以上版本才支持。

在指定的field的HTTP头部追加特殊的值value。如果这个头部没有被设置,那么将用value新建这个头部。value可以是一个字符串或者数组。 
注意:在res.append()之后调用app.set()函数将重置前面设置的值。

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

res.attachment([filename])

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

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

设置namevaluecookievalue参数可以是一串字符或者是转化为json字符串的对象。 
options是一个对象,其可以有下列的属性。

属性 类型 描述
domain String 设置cookie的域名。默认是你本app的域名。
expires Date cookie的过期时间,GMT格式。如果没有指定或者设置为0,则产生新的cookie。
httpOnly Boolean 这个cookie只能被web服务器获取的标示。
maxAge String 是设置过去时间的方便选项,其为过期时间到当前时间的毫秒值。
path String cookie的路径。默认值是/
secure Boolean 标示这个cookie只用被HTTPS协议使用。
signed Boolean 指示这个cookie应该是签名的。

res.cookie()所作的都是基于提供的options参数来设置Set-Cookie头部。没有指定任何的options,那么默认值在RFC6265中指定。

使用实例:

 
  1. res.cookie('name', 'tobi', {'domain':'.example.com', 'path':'/admin', 'secure':true});
关闭

用微信“扫一扫”