Express 3.x不再被维护

自上次更新(2015年8月1日)以来,尚未解决3.x中已知和未知的安全性和性能问题. 强烈建议使用最新版本的Express.

3.x API

express()

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

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

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

app.listen(3000)

Application

app.set(name, value)

将设置name分配给value .

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

app.get(name)

获取设置name值.

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

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

app.enable(name)

将设置name设置为true .

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

app.disable(name)

将设置name设置为false .

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

app.enabled(name)

检查设置name是否已启用.

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

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

app.disabled(name)

检查设置name是否被禁用.

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

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

app.configure([env], callback)

env匹配app.get('env') ,也称为process.env.NODE_ENV时,有条件地调用callback . 此方法由于遗留原因而保留,并且实际上是if语句,如以下代码片段所示. 这些功能不是为了使用所需app.set()和其他配置方法.

// all environments
app.configure(function () {
  app.set('title', 'My Application')
})

// development only
app.configure('development', function () {
  app.set('db uri', 'localhost/dev')
})

// production only
app.configure('production', function () {
  app.set('db uri', 'n.n.n.n/prod')
})

有效糖用于:

// all environments
app.set('title', 'My Application')

// development only
if (app.get('env') === 'development') {
  app.set('db uri', 'localhost/dev')
}

// production only
if (app.get('env') === 'production') {
  app.set('db uri', 'n.n.n.n/prod')
}

app.use([path], function)

使用给定的中间件function (带有可选的安装path ,默认为" /".

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

// simple logger
app.use(function (req, res, next) {
  console.log('%s %s', req.method, req.url)
  next()
})

// respond
app.use(function (req, res, next) {
  res.send('Hello World')
})

app.listen(3000)

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

一条路线将使紧跟其路径的任何路径都以" / "或""匹配. ". 例如: app.use('/apple', ...)将匹配/ apple/ apple / images/ apple / images / news/ apple.html/ apple.html.txt等.

这是一个具体示例,以使用express.static()中间件在./public中提供文件的典型用例为例:

// GET /javascripts/jquery.js
// GET /style.css
// GET /favicon.ico
app.use(express.static(path.join(__dirname, 'public')))

例如,假设您要为所有静态文件添加" / static"前缀,则可以使用"挂载"功能来支持此功能. 除非req.url包含此前缀,否则不会调用已安装的中间件函数,此时,在调用该函数时会删除该前缀. 这仅影响此功能,除非同时安装了它们,否则后续的中间件将看到带有" / static"的req.url .

// GET /static/javascripts/jquery.js
// GET /static/style.css
// GET /static/favicon.ico
app.use('/static', express.static(path.join(__dirname, 'public')))

使用app.use() "定义"中间件的顺序非常重要,它们是顺序调用的,因此这定义了中间件优先级. 例如,通常express.logger()是您要使用的第一个中间件,记录每个请求:

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

现在假设您要忽略记录静态文件的请求,但是要继续记录在logger()之后定义的路由和中间件,您只需在上面移动static()

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

另一个具体示例是从多个目录中提供文件,将" ./public"优先于其他目录:

app.use(express.static(path.join(__dirname, 'public')))
app.use(express.static(path.join(__dirname, 'files')))
app.use(express.static(path.join(__dirname, 'uploads')))

settings

提供以下设置来更改Express的行为:

  • env环境模式,默认为process.env.NODE_ENV或" development"
  • trust proxy启用反向代理支持,默认情况下禁用
  • jsonp callback name更改默认回调名称?callback =
  • json replacer JSON replacer回调,默认为null
  • json spaces用于格式化的JSON响应空间,在开发中默认为2,在生产中默认为0
  • case sensitive routing启用区分大小写,默认情况下禁用,将" / Foo"和" / foo"视为相同
  • strict routing启用严格路由,默认情况下路由器将" / foo"和" / foo /"视为相同
  • view cache启用视图模板编译缓存,默认情况下在生产中启用
  • view engine省略时使用的默认引擎扩展名
  • views视图目录路径,默认为" process.cwd()+'/ views'"

app.engine(ext, callback)

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

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

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

对于不提供.__express引擎,即开即用-或如果您希望将另一个扩展名"映射"到模板引擎,则可以使用此方法. 例如,将EJS模板引擎映射到" .html"文件:

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

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

某些模板引擎不遵循此约定,因此创建了consolidate.js库来映射节点的所有流行模板引擎都遵循此约定,从而使它们在Express中可以正常工作.

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

app.param([name], callback)

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

The following snippet illustrates how the callback is much like middleware, thus supporting async operations, however providing the additional value of the parameter, here named as id. An attempt to load the user is then performed, assigning req.user, otherwise passing an error to next(err).

app.param('user', function (req, res, next, id) {
  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'))
    }
  })
})

另外,您可以仅传递一个callback ,在这种情况下,您将有机会更改app.param() API. 例如, express-params定义了以下回调,该回调允许您将参数限制为给定的正则表达式.

此示例稍微先进一点,检查第二个参数是否为正则表达式,并返回与" user"参数示例非常相似的回调.

app.param(function (name, fn) {
  if (fn instanceof RegExp) {
    return function (req, res, next, val) {
      var captures
      if ((captures = fn.exec(String(val)))) {
        req.params[name] = captures
        next()
      } else {
        next('route')
      }
    }
  }
})

现在,该方法可用于有效验证参数,或解析它们以提供捕获组:

app.param('id', /^\d+$/)

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

app.param('range', /^(\w+)\.\.(\w+)?$/)

app.get('/range/:range', function (req, res) {
  var range = req.params.range
  res.send('from ' + range[1] + ' to ' + range[2])
})

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

app.VERB()方法提供Express中的路由功能,其中VERB是HTTP动词之一,例如app.post() . 可以给出多个回调,所有回调均被同等对待,并且行为类似于中间件,唯一的例外是这些回调可以调用next('route')绕过其余的路由回调. 此机制可用于对路由执行前提条件,然后在没有理由继续进行匹配的路由时将控制权传递给后续路由.

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

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

也可以使用正则表达式,如果您有非常具体的限制条件,则可以使用正则表达式,例如,以下表达式将匹配" GET / commits / 71dbb9c"以及" GET /commits/71dbb9c..4c084f9".

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

还可以传递几个回调,这对于重新使用加载资源,执行验证等的中间件很有用.

app.get('/user/:id', user.load, function () {
  // ...
})

这些回调也可以在数组内传递,这些数组在传递时仅被展平:

var middleware = [loadForum, loadThread]

app.get('/forum/:fid/thread/:tid', middleware, function () {
  // ...
})

app.post('/forum/:fid/thread/:tid', middleware, function () {
  // ...
})

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

此方法的功能类似于app.VERB()方法,但是它匹配所有HTTP动词.

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

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

或等效的:

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

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

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

app.locals

将应用程序局部变量提供给应用程序内呈现的所有模板. 这对于为模板以及应用程序级数据提供帮助功能很有用.

app.locals.title = 'My App'
app.locals.strftime = require('strftime')

app.locals对象是一个JavaScript Function ,当与对象一起调用时,它将属性合并到自身中,从而提供了一种简单的方式将现有对象公开为局部变量.

app.locals({
  title: 'My App',
  phone: '1-250-858-9990',
  email: 'me@myapp.com'
})

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

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

app.locals对象最终成为Javascript函数对象的结果是,您不得为自己的变量名重用现有的(本机)命名属性,例如name, apply, bind, call, arguments, length, constructor .

app.locals({ name: 'My App' })

console.log(app.locals.name)
// => return 'app.locals' in place of 'My App' (app.locals is a Function !)
// => if name's variable is used in a template, a ReferenceError will be returned.

本地命名属性的完整列表可以在许多规范中找到. JavaScript规范引入了原始属性,其中一些仍被现代引擎识别,然后EcmaScript规范在其上构建并规范化了属性集,添加了新属性并删除了不赞成使用的属性. 如果有兴趣,请签出函数和对象的属性.

默认情况下,Express仅公开单个应用程序级本地变量settings .

app.set('title', 'My App')
// use settings.title in a view

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

使用回调响应渲染的字符串来渲染view . 这是res.render()的应用程序级变体,否则行为相同.

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

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

app.routes

app.routes对象包含由相关的HTTP动词映射的所有定义的路由. 此对象可用于自省功能,例如Express在内部不仅将此用于路由,而且还提供默认值.

OPTIONS

行为,除非使用app.options() . 您的应用程序或框架也可以通过简单地从此对象中删除路由来删除路由.

console.log(app.routes)的输出:

{ get:
   [ { path: '/',
       method: 'get',
       callbacks: [Object],
       keys: [],
       regexp: /^\/\/?$/i },
     { path: '/user/:id',
       method: 'get',
       callbacks: [Object],
       keys: [{ name: 'id', optional: false }],
       regexp: /^\/user\/(?:([^\/]+?))\/?$/i } ],
  delete:
   [ { path: '/user/:id',
       method: 'delete',
       callbacks: [Object],
       keys: [Object],
       regexp: /^\/user\/(?:([^\/]+?))\/?$/i } ] }

app.listen()

绑定并侦听给定主机和端口上的连接,此方法与节点的http.Server#listen()相同 .

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

express()返回的app实际上是一个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)

The app.listen() method is simply a convenience method defined as, if you wish to use HTTPS or provide both, use the technique above.

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

Request

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

req.params

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

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

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

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

req.query

此属性是一个包含已解析查询字符串的对象,默认为{} .

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

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

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

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

req.body

此属性是一个包含已解析请求主体的对象. 该功能由bodyParser()中间件提供,尽管其他主体解析中间件也可以遵循此约定. 使用bodyParser()时,此属性默认为{} .

// POST user[name]=tobi&user[email]=tobi@learnboost.com
console.log(req.body.user.name)
// => "tobi"

console.log(req.body.user.email)
// => "tobi@learnboost.com"

// POST { "name": "tobi" }
console.log(req.body.name)
// => "tobi"

req.files

此属性是上载文件的对象. 该功能由bodyParser()中间件提供,尽管其他主体解析中间件也可以遵循此约定. 使用bodyParser()时,此属性默认为{} .

例如,如果文件字段名为" image",并且上传了文件,则req.files.image将包含以下File对象:

{ size: 74643,
  path: '/tmp/8ef9c52abe857867fd0a4e9a819d1876',
  name: 'edge.png',
  type: 'image/png',
  hash: false,
  lastModifiedDate: Thu Aug 09 2012 20:07:51 GMT-0700 (PDT),
  _writeStream:
   { path: '/tmp/8ef9c52abe857867fd0a4e9a819d1876',
     fd: 13,
     writable: false,
     flags: 'w',
     encoding: 'binary',
     mode: 438,
     bytesWritten: 74643,
     busy: false,
     _queue: [],
     _open: [Function],
     drainable: true },
  length: [Getter],
  filename: [Getter],
  mime: [Getter] }

bodyParser()中间件在内部利用可形成节点的模块,并接受相同的选项. 一个示例是keepExtensions formidable选项,默认为false ,在这种情况下,您会得到文件名" / tmp / 8ef9c52abe857867fd0a4e9a819d1876",而没有" .png"扩展名. 要启用此功能,您可以将它们传递给bodyParser()

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

req.param(name)

如果存在,则返回参数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
  • req.body
  • req.query

为了清楚起见,应该倾向于直接访问req.bodyreq.paramsreq.query ,除非您真正接受每个对象的输入.

req.route

当前匹配的Route包含几个属性,例如,路由的原始路径字符串,生成的regexp等.

app.get('/user/:id?', function (req, res) {
  console.dir(req.route)
})

上一片段的示例输出:

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

req.cookies

该对象需要使用cookieParser()中间件. 它包含用户代理发送的cookie. 如果没有发送cookie,则默认为{} .

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

req.signedCookies

该对象需要cookieParser(secret)中间件才能使用. 它包含由用户代理发送的已签名的cookie,未签名且可以使用. 已签名的cookie位于另一个对象中,以显示开发人员的意图. 否则,可能会对req.cookie值(很容易欺骗)进行恶意攻击. 请注意,对cookie签名不会使其"隐藏"或加密. 这只是防止篡改(因为用于签名的秘密是私有的). 如果没有发送签名的cookie,则默认为{} .

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

req.get(field)

获取不区分大小写的请求标头field . " Referrer"和" Referer"字段可以互换.

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

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

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

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

req.accepts(types)

检查给定types是否可接受,如果为true,则返回最佳匹配,否则返回undefined -在这种情况下,您应使用406"不可接受"进行响应.

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'])
req.accepts('html, json')
// => "json"

req.accepted

返回从最高质量到最低质量顺序排列的接受媒体类型的数组.

[ { value: 'application/json',
    quality: 1,
    type: 'application',
    subtype: 'json' },
   { value: 'text/html',
     quality: 0.5,
     type: 'text',
     subtype: 'html' } ]

req.is(type)

检查传入的请求是否包含" Content-Type"标头字段,并与给定的mime type相匹配.

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

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

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

req.ip

返回远程地址,或启用"信任代理"时-上游地址.

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

req.ips

当"信任代理"为true ,解析" X-Forwarded-For" IP地址列表并返回一个数组,否则返回一个空数组.

For example if the value were “client, proxy1, proxy2” you would receive the array ["client", "proxy1", "proxy2"] where “proxy2” is the furthest down-stream.

req.path

返回请求URL路径名.

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

req.host

从"主机"标头字段(没有端口号)返回主机名.

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

req.fresh

检查请求是否新鲜-aka Last-Modified和/或ETag仍然匹配,指示资源为"新鲜".

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

req.stale

检查请求是否过时-aka Last-Modified和/或ETag不匹配,表明资源是"过时".

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

req.xhr

检查是否发出了将" X-Requested-With"标头字段设置为" XMLHttpRequest"(jQuery等)的请求.

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

req.protocol

TLS要求时,返回协议字符串" http"或" https". 启用"信任代理"设置后,将信任" X-Forwarded-Proto"标头字段. 如果您在向您提供https的反向代理后面运行,则可以启用它.

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

req.secure

Check if a TLS connection is established. This is a short-hand for:

console.dir(req.protocol === 'https')
// => true

req.subdomains

以数组形式返回子域.

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

req.originalUrl

此属性非常类似于req.url ,但是它保留了原始请求url,允许您出于内部路由目的自由地重写req.url . 例如, app.use()的"安装"功能将重写req.url以剥离安装点.

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

req.acceptedLanguages

返回从最高质量到最低质量的顺序排列的接受语言.

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

req.acceptedCharsets

返回从最高质量到最低质量顺序排列的接受字符集数组.

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

req.acceptsCharset(charset)

检查给定的charset是否可接受.

req.acceptsLanguage(lang)

检查给定的lang是否可接受.

Response

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

res.status(code)

节点的res.statusCode=链接别名.

res.status(404).sendfile('path/to/404.png')

res.set(field, [value])

将标头field设置为value ,或传递一个对象以一次设置多个字段.

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

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

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

res.get(field)

获取不区分大小写的响应标头field .

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

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

将Cookie name设置为value ,它可以是转换为JSON的字符串或对象. path选项默认为" /".

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

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

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

可以传递一个对象,然后将其序列化为JSON,该对象由bodyParser()中间件自动解析.

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

通过此方法也支持签名的cookie. 只需通过signed选项即可. 给定res.cookie()将使用传递给express.cookieParser(secret)对值进行签名.

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

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

res.clearCookie(name, [options])

清除cookie name . path选项默认为" /".

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

res.redirect([status], url)

使用默认为302"已找到"的可选status代码重定向到给定的url .

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

Express支持几种形式的重定向,首先是用于重定向到其他站点的标准URI:

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

第二种形式是相对于路径名的重定向,例如,如果您使用的是http://example.com/admin/post/new ,则以下对/admin重定向将使您进入http://example.com/admin

res.redirect('/admin')

下一个重定向是相对于应用程序的mount点. 例如,如果您在/blog处挂载了博客应用程序,则理想情况下它不知道其挂载位置,因此/admin/post/new的重定向将仅向您提供http://example.com/admin/post/new ,以下相对于安装的重定向将为您提供http://example.com/blog/admin/post/new

res.redirect('admin/post/new')

路径名相对重定向也是可能的. 如果您位于http://example.com/admin/post/new ,则以下重定向将使您进入http//example.com/admin/post

res.redirect('..')

最后一种特殊情况是back重定向,即重定向回Referer(或Referrer),丢失时默认为/ .

res.redirect('back')

res.location

设置位置标题.

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

您可以使用与res.redirect()相同的urls .

例如,如果您的应用程序安装在/blog ,则以下内容会将location标头设置为/blog/admin

res.location('admin')

res.charset

分配字符集. 默认为" utf-8".

res.charset = 'value'
res.send('<p>some html</p>')
// => Content-Type: text/html; charset=value

res.send([body|status], [body])

发送回复.

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

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

给定Buffer除非预先定义如下,否则将Content-Type设置为" application / octet-stream":

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

当给出一个String ,Content-Type默认设置为" text / html":

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

当给定ArrayObject ,Express将以JSON表示形式进行响应:

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

最后,如果给出的Number没有前面提到的任何正文,则会为您分配一个响应正文字符串. 例如200将响应将显示文本"确定",以及404"未找到"等等.

res.send(200)
res.send(404)
res.send(500)

res.json([status|body], [body])

发送JSON响应. 传递对象或数组时,此方法与res.send()相同,但是,从技术上讲,它们在非对象(空,未定义等)的显式JSON转换中可以使用,尽管它们在技术上不是有效的JSON.

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

res.jsonp([status|body], [body])

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

res.jsonp(null)
// => null

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

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

By default the JSONP callback name is simply callback, however you may alter this with the jsonp callback name setting. The following are some examples of JSONP responses using the same code:

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

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

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

res.type(type)

套在Content-Type到的MIME查找type时,或当"/"是存在于内容类型被简单地设置该文字值.

res.type('.html')
res.type('html')
res.type('json')
res.type('application/json')
res.type('png')

p res.contentType(type)res.contentType(type) .

res.format(object)

存在请求时,对请求的"接受"标头字段执行内容协商. 此方法使用req.accepted ,这是根据其质量值排序的可接受类型的数组,否则将调用第一个回调. 如果未执行任何匹配,则服务器将以406"不可接受"进行响应,或调用default回调.

当选择了回调时,将为您设置Content-Type,但是您可以使用res.set()res.type()等在回调中更改此res.type() .

以下示例将在Accept标头字段设置为" application / json"或" / json"时以{ "message": "hey" }响应,但是,如果给出" / *",则将" hey"作为响应.

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

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

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

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

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

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

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

res.attachment([filename])

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

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

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

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

在给定path传输文件.

根据文件名的扩展名自动默认Content-Type响应头字段. 传输完成或发生错误时,将调用回调fn(err) .

Options:

  • 以毫秒为单位的maxAge默认为0
  • root为相对文件名根目录

此方法提供了对文件服务的细粒度支持,如以下示例所示:

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

  req.user.mayViewFilesFrom(uid, function (yes) {
    if (yes) {
      res.sendfile('/uploads/' + uid + '/' + file)
    } else {
      res.send(403, 'Sorry! you cant see that.')
    }
  })
})

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

将文件作为"附件"在path传输,通常浏览器会提示用户下载. 默认情况下,Content-Disposition" filename ="参数(也将出现在浏览器对话框中的参数)设置为path ,但是您可以提供替代filename .

当发生错误或传输完成时,将调用可选的回调fn . 此方法使用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, keep in mind the response may be partially-sent
    // so check res.headerSent
  } else {
    // decrement a download credit etc
  }
})

加入给定的links以填充"链接"响应标题字段.

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

p产量:

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

res.locals

响应局部变量的作用域是请求,因此仅可用于在该请求/响应周期中呈现的视图(如果有). 否则,此API与app.locals相同.

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

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

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

使用回调响应渲染的字符串来渲染view . 发生错误时,将next(err)内部调用next(err) . 提供回调时,可能的错误和呈现的字符串均会传递,并且不会执行自动响应.

res.render('index', function (err, html) {
  // ...
})

res.render('user', { name: 'Tobi' }, function (err, html) {
  // ...
})

Middleware

basicAuth()

基本身份验证中间件,使用用户名填充req.user .

简单的用户名和密码:

app.use(express.basicAuth('username', 'password'))

回调验证:

app.use(express.basicAuth(function (user, pass) {
  return user === 'tj' && pass === 'wahoo'
}))

异步回调验证,接受fn(err, user) ,在这种情况下, req.user将是传递的用户对象.

app.use(express.basicAuth(function (user, pass, fn) {
  User.authenticate({ user: user, pass: pass }, fn)
}))

bodyParser()

请求主体解析中间件,支持JSON,urlencoded和多部分请求. 该中间件只是json()urlencoded()multipart()中间件的包装.

app.use(express.bodyParser())

// is equivalent to:
app.use(express.json())
app.use(express.urlencoded())
app.use(express.multipart())

为了安全起见,如果您的应用程序不需要文件上传,则最好禁用它. 为此,仅使用所需的中间件,即不要使用bodyParsermultipart()中间件:

app.use(express.json())
app.use(express.urlencoded())

如果您的应用程序需要文件上传,则应设置一个处理这些文件的策略 .

compress()

用gzip / deflate压缩响应数据. 该中间件应放在堆栈中的"较高"位置,以确保可以压缩所有响应.

app.use(express.logger())
app.use(express.compress())
app.use(express.methodOverride())
app.use(express.bodyParser())

cookieParser()

解析Cookie头字段,并用cookie名称作为键的对象填充req.cookies . (可选)您可以通过传递secret字符串来启用签名Cookie支持.

app.use(express.cookieParser())
app.use(express.cookieParser('some secret'))

cookieSession()

提供基于cookie的会话,并填充req.session . 该中间件具有以下选项:

  • 默认为connect.sess key cookie名称
  • secret可防止篡改Cookie
  • cookie会话cookie设置,默认为{ path: '/', httpOnly: true, maxAge: null }
  • proxy在设置安全Cookie时信任反向代理(通过" x-forwarded-proto")
app.use(express.cookieSession())

要清除Cookie,只需在响应之前将会话分配为null:

req.session = null

csrf()

CSRF保护中间件.

默认情况下,该中间件生成一个名为" _csrf"的令牌,该令牌应添加到在隐藏的表单字段,查询字符串等req.csrfToken()状态发生变化的请求中.此令牌已根据req.csrfToken()验证.

默认value函数检查req.body bodyParser()中间件生成的bodyParser() ,由query()生成的req.query和" X-CSRF-Token"头字段.

该中间件需要会话支持,因此应将其添加到session()下方.

directory()

目录服务中间件服务于给定path . 该中间件可以与static()配对以提供文件,从而提供功能齐全的文件浏览器.

app.use(express.directory('public'))
app.use(express.static('public'))

该中间件接受以下选项:

  • hidden显示隐藏(点)文件. 默认为false.
  • icons显示图标. 默认为false.
  • filter将此过滤器功能应用于文件. 默认为false.

by  ICOPY.SITE