Request

req.params

这是一个数组对象,命名过的参数会以键值对的形式存放。 比如你有一个路由/user/:name, "name"属性会存放在req.params.name. 这个对象默认为 {}.

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

当使用正则表达式定义路由的时候,req.params[N]会是这个应用这个正则后的捕获分组, N 是代表的是第N个捕获分组。这个规则同样适用于全匹配的路由,如 /file/*:

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

req.query

这是一个解析过的请求参数对象,默认为{}.

  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.body

这个对应的是解析过的请求体。这个特性是bodyParser() 中间件提供,其它的请求体解析中间件可以放在这个中间件之后。当bodyParser()中间件使用后,这个对象默认为 {}

  1. // POST user[name]=tobi&user[email]=tobi@learnboost.com
  2. req.body.user.name
  3. // => "tobi"
  4. req.body.user.email
  5. // => "tobi@learnboost.com"
  6. // POST { "name": "tobi" }
  7. req.body.name
  8. // => "tobi"

req.files

这是上传的文件的对象。这个特性是bodyParser() 中间件提供,其它的请求体解析中间件可以放在这个中间件之后。当bodyParser()中间件使用后,这个对象默认为 {}

例如 file 字段被命名为"image", 当一个文件上传完成后,req.files.image 将会包含下面的 File 对象:

  1. { size: 74643,
  2. path: '/tmp/8ef9c52abe857867fd0a4e9a819d1876',
  3. name: 'edge.png',
  4. type: 'image/png',
  5. hash: false,
  6. lastModifiedDate: Thu Aug 09 2012 20:07:51 GMT-0700 (PDT),
  7. _writeStream:
  8. { path: '/tmp/8ef9c52abe857867fd0a4e9a819d1876',
  9. fd: 13,
  10. writable: false,
  11. flags: 'w',
  12. encoding: 'binary',
  13. mode: 438,
  14. bytesWritten: 74643,
  15. busy: false,
  16. _queue: [],
  17. _open: [Function],
  18. drainable: true },
  19. length: [Getter],
  20. filename: [Getter],
  21. mime: [Getter] }

bodyParser() 中间件是在内部使用node-formidable来处理文件请求,所以接收的参数是一致的。 举个例子,使用formidable的选项keepExtensions , 它默认为 false , 在上面的例子可以看到给出的文件名"/tmp/8ef9c52abe857867fd0a4e9a819d1876" 不包含".png" 扩展名. 为了让它可以保留扩展名,你可以把参数传给 bodyParser():

  1. app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/my/files' }));

req.param(name)

返回 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
    直接访问 req.body, req.params, 和 req.query 应该更合适,除非你真的需要从这几个对象里同时接受输入。

req.route

这个对象里是当前匹配的 Route 里包含的属性,比如原始路径字符串,产生的正则,等等

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

上面代码的一个输出:

  1. { path: '/user/:id?',
  2. method: 'get',
  3. callbacks: [ [Function] ],
  4. keys: [ { name: 'id', optional: true } ],
  5. regexp: /^\/user(?:\/([^\/]+?))?\/?$/i,
  6. params: [ id: '12' ] }

req.cookies

当使用 cookieParser()中间件之后,这个对象默认为{}, 它也包含了用户代理传过来的cookies。

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

req.signedCookies

当使用了cookieParser(secret) 中间件后,这个对象默认为{}, 否则包含了用户代理传回来的签名后的cookie,并等待使用。签名后的cookies被放在一个单独的对象里,恶意攻击者可以很简单的替换掉req.cookie 的值。需要注意的是签名的cookie不代表它是隐藏的或者加密的,这个只是简单的阻止篡改cookie。

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

req.get(field)

获取请求头里的field的值,大小写不敏感. 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.accepts(types)

. 检查给定的types 是不是可以接受类型,当可以接受时返回最匹配的,否则返回undefined - 这个时候你应该响应一个406 "Not Acceptable".

type 的值可能是单一的一个mime类型字符串,比如 "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. req.accepts('html, json');
  20. // => "json"

req.accepted

返回一个从高质量到低质量排序的接受媒体类型数组

  1. [ { value: 'application/json',
  2. quality: 1,
  3. type: 'application',
  4. subtype: 'json' },
  5. { value: 'text/html',
  6. quality: 0.5,
  7. type: 'text',
  8. subtype: 'html' } ]

req.is(type)

检查请求的文件头是不是包含"Content-Type" 字段, 它匹配给定的type.

  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

req.ip

返回远程地址,或者当“信任代理”使用时,返回上一级的地址

  1. req.ip
  2. // => "127.0.0.1"

req.ips

当设置"trust proxy" 为 true时, 解析"X-Forwarded-For" 里的ip地址列表,并返回一个数组 否则返回一个空数组 举个例子,如果"X-Forwarded-For" 的值为"client, proxy1, proxy2" 你将会得到数组["client", "proxy1", "proxy2"] 这里可以看到 "proxy2" 是最近一个使用的代理

req.path

返回请求的URL的路径名

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

req.host

返回从"Host"请求头里取的主机名,不包含端口号。

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

req.fresh

判断请求是不是新的-通过对Last-Modified 或者 ETag 进行匹配, 来标明这个资源是不是"新的".

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

req.stale

判断请求是不是旧的-如果Last-Modified 或者 ETag 不匹配, 标明这个资源是"旧的". Check if the request is stale - aka Last-Modified and/or the ETag do not match, indicating that the resource is "stale".

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

req.xhr

判断请求头里是否有"X-Requested-With"这样的字段并且值为"XMLHttpRequest", jQuery等库发请求时会设置这个头

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

req.protocol

返回标识请求协议的字符串,一般是"http",当用TLS请求的时候是"https"。 当"trust proxy" 设置被激活, "X-Forwarded-Proto" 头部字段会被信任。 如果你使用了一个支持https的反向代理,那这个可能是激活的。

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

req.secure

检查TLS 连接是否已经建立。 这是下面的缩写:

  1. 'https' == req.protocol;

req.subdomains

把子域当作一个数组返回

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

req.originalUrl

这个属性很像 req.url, 但是它保留了原始的url。 这样你在做内部路由的时候可以重写req.url。 比如app.use()的挂载功能会重写 req.url,把从它挂载的点开始

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

req.acceptedLanguages

返回一个从高质量到低质量排序的接受语言数组

  1. Accept-Language: en;q=.5, en-us
  2. // => ['en-us', 'en']

req.acceptedCharsets

返回一个从高质量到低质量排序的可接受的字符集数组

  1. Accept-Charset: iso-8859-5;q=.2, unicode-1-1;q=0.8
  2. // => ['unicode-1-1', 'iso-8859-5']

req.acceptsCharset(charset)

检查给定的charset 是不是可以接受的

req.acceptsLanguage(lang)

检查给定的 lang 是不是可以接受的