对 Express 3.x 的技术支持即将结束
这一版本系列将来仍会继续提供安全补丁和 bug 更新,直至 2015 年 7 月。强烈建议您升级到 Express 4.x 。
Express 3.x API 中文手册
express()
Creates an Express application. The express()
function is a top-level function exported by the express module.
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
配合其它一些配置方法后,没有必要再使用这个方法。
// 所有环境
app.configure(function(){
app.set('title', 'My Application');
})
// 开发环境
app.configure('development', function(){
app.set('db uri', 'localhost/dev');
})
// 只用于生产环境
app.configure('production', function(){
app.set('db uri', 'n.n.n.n/prod');
})
更高效且直接的代码如下:
// 所有环境
app.set('title', 'My Application');
// 只用于开发环境
if ('development' == app.get('env')) {
app.set('db uri', 'localhost/dev');
}
// 只用于生产环境
if ('production' == app.get('env')) {
app.set('db uri', 'n.n.n.n/prod');
}
app.use([path], function)
使用中间件 function
,可选参数 path
默认是 “/”。
var express = require('express');
var app = express();
// 一个简单的 logger
app.use(function(req, res, next){
console.log('%s %s', req.method, req.url);
next();
});
// 响应
app.use(function(req, res, next){
res.send('Hello World');
});
app.listen(3000);
The “mount” path is stripped and is not visible
to the middleware function
. The main effect of this feature is that
mounted middleware may operate without code changes regardless of its “prefix”
pathname.
A route will match any path, which follows its path immediately with either a “/
” or a “.
”. For example: app.use('/apple', ...)
will match /apple, /apple/images, /apple/images/news, /apple.html, /apple.html.txt, and so on.
Here’s a concrete example, take the typical use-case of serving files in ./public
using the express.static()
middleware:
// GET /javascripts/jquery.js
// GET /style.css
// GET /favicon.ico
app.use(express.static(__dirname + '/public'));
Say for example you wanted to prefix all static files with “/static”, you could
use the “mounting” feature to support this. Mounted middleware functions are not
invoked unless the req.url
contains this prefix, at which point
it is stripped when the function is invoked. This affects this function only,
subsequent middleware will see req.url
with “/static” included
unless they are mounted as well.
// GET /static/javascripts/jquery.js
// GET /static/style.css
// GET /static/favicon.ico
app.use('/static', express.static(__dirname + '/public'));
The order of which middleware are “defined” using app.use()
is
very important, they are invoked sequentially, thus this defines middleware
precedence. For example usually express.logger()
is the very
first middleware you would use, logging every request:
app.use(express.logger());
app.use(express.static(__dirname + '/public'));
app.use(function(req, res){
res.send('Hello');
});
Now suppose you wanted to ignore logging requests for static files, but to
continue logging routes and middleware defined after logger()
,
you would simply move static()
above:
app.use(express.static(__dirname + '/public'));
app.use(express.logger());
app.use(function(req, res){
res.send('Hello');
});
Another concrete example would be serving files from multiple directories, giving precedence to “./public” over the others:
app.use(express.static(__dirname + '/public'));
app.use(express.static(__dirname + '/files'));
app.use(express.static(__dirname + '/uploads'));
settings
下面的内建的可以改变 Express 行为的设置:
env
运行时环境,默认为 process.env.NODE_ENV 或者 “development”trust proxy
激活反向代理,默认是未激活状态jsonp callback name
修改 ?callback= 的默认 callback 的名字json replacer
JSON 替换时的回调, 默认为 nulljson spaces
JSON 响应被格式化时的空格数量,开发环境下是 2 ,生产环境是 0case sensitive routing
路由的大小写敏感, 默认是关闭状态,”/Foo” 和 “/foo” 被认为是一样的strict routing
路由的严格格式, 默认情况下 “/foo” 和 “/foo/” 被路由认为是一样的view cache
E模板缓存,在生产环境中是默认开启的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专门把所有的node流行的模板引擎进行了包装,这样它们在 Express 内部看起来就一样了。
var engines = require('consolidate');
app.engine('haml', engines.haml);
app.engine('html', engines.hogan);
app.param([name], callback)
路由参数的处理逻辑。比如当 :user
出现在一个路由路径中,你也许会自动载入加载用户的逻辑,并把它放置到 req.user
, 或者校验一下输入的参数是否正确。
下面的代码片段展示了 callback
很像中间件,但是在参数里多加了一个值,这里名为 id
。它会尝试加载用户信息,然后赋值给 req.user
, 否则就传递错误 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)
The app.VERB()
methods provide the routing functionality
in Express, where VERB is one of the HTTP verbs, such
as app.post()
. Multiple callbacks may be given, all are treated
equally, and behave just like middleware, with the one exception that
these callbacks may invoke next('route')
to bypass the
remaining route callback(s). This mechanism can be used to perform pre-conditions
on a route then pass control to subsequent routes when there is no reason to proceed
with the route matched.
The following snippet illustrates the most simple route definition possible. Express translates the path strings to regular expressions, used internally to match incoming requests. Query strings are not considered when peforming these matches, for example “GET /” would match the following route, as would “GET /?name=tobi”.
app.get('/', function(req, res){
res.send('hello world');
});
Regular expressions may also be used, and can be useful if you have very specific restraints, for example the following would match “GET /commits/71dbb9c” as well as “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);
});
Several callbacks may also be passed, useful for re-using middleware that load resources, perform validations, etc.
app.get('/user/:id', user.load, function(){
// ...
})
These callbacks may be passed within arrays as well, these arrays are simply flattened when passed:
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);
Or the equivalent:
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'
});
app.locals.title
// => 'My App'
app.locals.email
// => 'me@myapp.com'
app.locals
对象最终会是一个 Javascript 函数对象,你不可以使用 Functions 和 Objects 内置的属性,比如 name、apply、bind、call、arguments、length、constructor
。
app.locals({name: 'My App'});
app.locals.name
// => 返回 'app.locals' 而不是 'My App' (app.locals 是一个函数 !)
// => 如果 name 变量用在一个模板里,则返回一个 ReferenceError 。
全部的保留字列表可以在很多规范里找到。 JavaScript 规范 介绍了原来的属性,有一些还会被现代的 JavaScript 引擎识别,EcmaScript 规范 在它的基础上,统一了值,添加了一些,删除了一些废弃的。如果感兴趣,可以看看 Functions 和 Objects 的属性值。
默认情况下Express只有一个应用程序级本地变量,它是 settings
。
app.set('title', 'My App');
// 在 view 里使用 settings.title
app.render(view, [options], callback)
渲染 view
, 回调函数 callback
用来处理返回的渲染后的字符串。这个是 res.render()
的应用程序级版本,它们的行为是一样的。
app.render('email', function(err, html){
// ...
});
app.render('email', { name: 'Tobi' }, function(err, html){
// ...
});
app.routes
The app.routes
对象存储了所有的被 HTTP verb 定义路由。这个对象可以用在一些内部功能上,比如 Express 不仅用它来做路由分发,同时在没有 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()
在给定的主机和端口上监听请求,这个和 node 文档中的 http.Server#listen() 是一致的。
var express = require('express');
var app = express();
app.listen(3000);
express()
返回的 app
实际上是一个 JavaScript
Function
,它被设计为传给 node 的 http servers 作为处理请求的回调函数。因为 app 不是从 HTTP 或者 HTTPS 继承来的,它只是一个简单的回调函数,你可以以同一份代码同时处理 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()
方法只是一个快捷方法,如果你想使用 HTTPS ,或者同时提供 HTTP 和 HTTPS ,可以使用上面的代码。
app.listen = function(){
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
Request
req.params
This property is an array containing properties mapped to the named route “parameters”.
For example if you have the route /user/:name
, then the “name” property
is available to you as req.params.name
. This object defaults to {}
.
// GET /user/tj
req.params.name
// => "tj"
When a regular expression is used for the route definition, capture groups
are provided in the array using req.params[N]
, where N
is the nth capture group. This rule is applied to unnamed wild-card matches
with string routes such as /file/*
:
// GET /file/javascripts/jquery.js
req.params[0]
// => "javascripts/jquery.js"
req.query
This property is an object containing the parsed query-string,
defaulting to {}
.
// 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.body
This property is an object containing the parsed request body. This feature
is provided by the bodyParser()
middleware, though other body
parsing middleware may follow this convention as well. This property
defaults to {}
when bodyParser()
is used.
// POST user[name]=tobi&user[email]=tobi@learnboost.com
req.body.user.name
// => "tobi"
req.body.user.email
// => "tobi@learnboost.com"
// POST { "name": "tobi" }
req.body.name
// => "tobi"
req.files
This property is an object of the files uploaded. This feature
is provided by the bodyParser()
middleware, though other body
parsing middleware may follow this convention as well. This property
defaults to {}
when bodyParser()
is used.
For example if a file field was named “image”,
and a file was uploaded, req.files.image
would contain
the following File
object:
{ 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] }
The bodyParser()
middleware utilizes the
node-formidable
module internally, and accepts the same options. An example of this
is the keepExtensions
formidable option, defaulting to false
which in this case gives you the filename “/tmp/8ef9c52abe857867fd0a4e9a819d1876” void of
the “.png” extension. To enable this, and others you may pass them to bodyParser()
:
app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/my/files' }));
req.param(name)
Return the value of param name
when present.
// ?name=tobi
req.param('name')
// => "tobi"
// POST name=tobi
req.param('name')
// => "tobi"
// /user/tobi for /user/:name
req.param('name')
// => "tobi"
Lookup is performed in the following order:
req.params
req.body
req.query
Direct access to req.body
, req.params
,
and req.query
should be favoured for clarity - unless
you truly accept input from each object.
req.route
The currently matched Route
containing
several properties such as the route’s original path
string, the regexp generated, and so on.
app.get('/user/:id?', function(req, res){
console.log(req.route);
});
Example output from the previous snippet:
{ path: '/user/:id?',
method: 'get',
callbacks: [ [Function] ],
keys: [ { name: 'id', optional: true } ],
regexp: /^\/user(?:\/([^\/]+?))?\/?$/i,
params: [ id: '12' ] }
req.cookies
This object requires the cookieParser()
middleware for use.
It contains cookies sent by the user-agent. If no cookies are sent, it
defaults to {}
.
// Cookie: name=tj
req.cookies.name
// => "tj"
req.signedCookies
This object requires the cookieParser(secret)
middleware for use.
It contains signed cookies sent by the user-agent, unsigned and ready for use.
Signed cookies reside in a different object to show developer intent; otherwise,
a malicious attack could be placed on req.cookie
values (which are easy to spoof).
Note that signing a cookie does not make it “hidden” or encrypted; this simply
prevents tampering (because the secret used to sign is private). If no signed
cookies are sent, it defaults to {}
.
// Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3
req.signedCookies.user
// => "tobi"
req.get(field)
Get the case-insensitive request header field
. The “Referrer” and “Referer” fields are interchangeable.
req.get('Content-Type');
// => "text/plain"
req.get('content-type');
// => "text/plain"
req.get('Something');
// => undefined
p Aliased as req.header(field)
.
req.accepts(types)
Check if the given types
are acceptable, returning
the best match when true, otherwise undefined
- in which
case you should respond with 406 “Not Acceptable”.
The type
value may be a single mime type string
such as “application/json”, the extension name
such as “json”, a comma-delimited list or an array. When a list
or array is given the best match, if any is returned.
// 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
Return an array of Accepted media types ordered from highest quality to lowest.
[ { value: 'application/json',
quality: 1,
type: 'application',
subtype: 'json' },
{ value: 'text/html',
quality: 0.5,
type: 'text',
subtype: 'html' } ]
req.is(type)
Check if the incoming request contains the “Content-Type”
header field, and it matches the give 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
Return the remote address, or when “trust proxy” is enabled - the upstream address.
req.ip
// => "127.0.0.1"
req.ips
When “trust proxy” is true
, parse
the “X-Forwarded-For” ip address list
and return an array, otherwise an empty
array is returned.
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
Returns the request URL pathname.
// example.com/users?sort=desc
req.path
// => "/users"
req.host
Returns the hostname from the “Host” header field (void of portno).
// Host: "example.com:3000"
req.host
// => "example.com"
req.fresh
Check if the request is fresh - aka Last-Modified and/or the ETag still match, indicating that the resource is “fresh”.
req.fresh
// => true
req.stale
Check if the request is stale - aka Last-Modified and/or the ETag do not match, indicating that the resource is “stale”.
req.stale
// => true
req.xhr
Check if the request was issued with the “X-Requested-With” header field set to “XMLHttpRequest” (jQuery etc).
req.xhr
// => true
req.protocol
Return the protocol string “http” or “https” when requested with TLS. When the “trust proxy” setting is enabled the “X-Forwarded-Proto” header field will be trusted. If you’re running behind a reverse proxy that supplies https for you this may be enabled.
js req.protocol // => “http” ~~~
req.secure
Check if a TLS connection is established. This is a short-hand for:
'https' == req.protocol;
req.subdomains
Return subdomains as an array.
// Host: "tobi.ferrets.example.com"
req.subdomains
// => ["ferrets", "tobi"]
req.originalUrl
This property is much like req.url
, however it retains
the original request url, allowing you to rewrite req.url
freely for internal routing purposes. For example the “mounting” feature
of app.use() will rewrite req.url
to
strip the mount point.
// GET /search?q=something
req.originalUrl
// => "/search?q=something"
req.acceptedLanguages
Return an array of Accepted languages ordered from highest quality to lowest.
Accept-Language: en;q=.5, en-us
// => ['en-us', 'en']
req.acceptedCharsets
Return an array of Accepted charsets ordered from highest quality to lowest.
Accept-Charset: iso-8859-5;q=.2, unicode-1-1;q=0.8
// => ['unicode-1-1', 'iso-8859-5']
req.acceptsCharset(charset)
Check if the given charset
are acceptable.
req.acceptsLanguage(lang)
Check if the given lang
are acceptable.
Response
res.status(code)
Chainable alias of node’s res.statusCode=
.
res.status(404).sendfile('path/to/404.png');
res.set(field, [value])
Set header field
to value
, or pass an object to set multiple fields at once.
res.set('Content-Type', 'text/plain');
res.set({
'Content-Type': 'text/plain',
'Content-Length': '123',
'ETag': '12345'
})
Aliased as res.header(field, [value])
.
res.get(field)
Get the case-insensitive response header field
.
res.get('Content-Type');
// => "text/plain"
res.cookie(name, value, [options])
Set cookie name
to value
, which may be a string or object converted to JSON. The path
option defaults to “/”.
res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true });
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
The maxAge
option is a convenience option for setting “expires”
relative to the current time in milliseconds. The following is equivalent to
the previous example.
res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
An object may be passed which is then serialized as JSON, which is
automatically parsed by the bodyParser()
middleware.
res.cookie('cart', { items: [1,2,3] });
res.cookie('cart', { items: [1,2,3] }, { maxAge: 900000 });
Signed cookies are also supported through this method. Simply
pass the signed
option. When given res.cookie()
will use the secret passed to express.cookieParser(secret)
to sign the value.
res.cookie('name', 'tobi', { signed: true });
Later you may access this value through the req.signedCookie object.
res.clearCookie(name, [options])
Clear cookie name
. The path
option defaults to “/”.
res.cookie('name', 'tobi', { path: '/admin' });
res.clearCookie('name', { path: '/admin' });
res.redirect([status], url)
Redirect to the given url
with optional status
code
defaulting to 302 “Found”.
res.redirect('/foo/bar');
res.redirect('http://example.com');
res.redirect(301, 'http://example.com');
res.redirect('../login');
Express supports a few forms of redirection, first being a fully qualified URI for redirecting to a different site:
res.redirect('http://google.com');
The second form is the pathname-relative redirect, for example
if you were on http://example.com/admin/post/new
, the
following redirect to /admin
would land you at http://example.com/admin
:
res.redirect('/admin');
This next redirect is relative to the mount
point of the application. For example
if you have a blog application mounted at /blog
, ideally it has no knowledge of
where it was mounted, so where a redirect of /admin/post/new
would simply give you
http://example.com/admin/post/new
, the following mount-relative redirect would give
you http://example.com/blog/admin/post/new
:
res.redirect('admin/post/new');
Pathname relative redirects are also possible. If you were
on http://example.com/admin/post/new
, the following redirect
would land you at http//example.com/admin/post
:
res.redirect('..');
The final special-case is a back
redirect, redirecting back to
the Referer (or Referrer), defaulting to /
when missing.
res.redirect('back');
res.location
Set the location header.
res.location('/foo/bar');
res.location('foo/bar');
res.location('http://example.com');
res.location('../login');
res.location('back');
You can use the same kind of urls
as in res.redirect()
.
For example, if your application is mounted at /blog
,
the following would set the location
header to
/blog/admin
:
res.location('admin')
res.charset
Assign the charset. Defaults to “utf-8”.
res.charset = 'value';
res.send('<p>some html</p>');
// => Content-Type: text/html; charset=value
res.send([body|status], [body])
Send a response.
res.send(new Buffer('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);
This method performs a myriad of useful tasks for simple non-streaming responses such as automatically assigning the Content-Length unless previously defined and providing automatic HEAD and HTTP cache freshness support.
When a Buffer
is given
the Content-Type is set to “application/octet-stream”
unless previously defined as shown below:
res.set('Content-Type', 'text/html');
res.send(new Buffer('<p>some html</p>'));
When a String
is given the
Content-Type is set defaulted to “text/html”:
res.send('<p>some html</p>');
When an Array
or Object
is
given Express will respond with the JSON representation:
res.send({ user: 'tobi' })
res.send([1,2,3])
Finally when a Number
is given without
any of the previously mentioned bodies, then a response
body string is assigned for you. For example 200 will
respond will the text “OK”, and 404 “Not Found” and so on.
res.send(200)
res.send(404)
res.send(500)
res.json([status|body], [body])
Send a JSON response. This method is identical
to res.send()
when an object or
array is passed, however it may be used for
explicit JSON conversion of non-objects (null, undefined, etc),
though these are technically not valid JSON.
res.json(null)
res.json({ user: 'tobi' })
res.json(500, { error: 'message' })
res.jsonp([status|body], [body])
Send a JSON response with JSONP support. This method is identical
to res.json()
however opts-in to JSONP callback
support.
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)
Sets the Content-Type to the mime lookup of type
,
or when “/” is present the Content-Type is simply set to this
literal value.
res.type('.html');
res.type('html');
res.type('json');
res.type('application/json');
res.type('png');
p Aliased as res.contentType(type)
.
res.format(object)
Performs content-negotiation on the request Accept header
field when present. This method uses req.accepted
, an array of
acceptable types ordered by their quality values, otherwise the
first callback is invoked. When no match is performed the server
responds with 406 “Not Acceptable”, or invokes the default
callback.
The Content-Type is set for you when a callback is selected,
however you may alter this within the callback using res.set()
or res.type()
etcetera.
The following example would respond with { "message": "hey" }
when the Accept header field is set to “application/json” or “/json”,
however if “/*” is given then “hey” will be the response.
res.format({
'text/plain': function(){
res.send('hey');
},
'text/html': function(){
res.send('<p>hey</p>');
},
'application/json': function(){
res.send({ message: 'hey' });
}
});
In addition to canonicalized MIME types you may also use extnames mapped to these types, providing a slightly less verbose implementation:
res.format({
text: function(){
res.send('hey');
},
html: function(){
res.send('<p>hey</p>');
},
json: function(){
res.send({ message: 'hey' });
}
});
res.attachment([filename])
Sets the Content-Disposition header field to “attachment”. If
a filename
is given then the Content-Type will be
automatically set based on the extname via res.type()
,
and the Content-Disposition’s “filename=” parameter will be set.
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]])
Transfer the file at the given path
.
Automatically defaults the Content-Type response header field based
on the filename’s extension. The callback fn(err)
is
invoked when the transfer is complete or when an error occurs.
Options:
maxAge
in milliseconds defaulting to 0root
root directory for relative filenames
This method provides fine-grained support for file serving as illustrated in the following example:
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.send(403, 'Sorry! you cant see that.');
}
});
});
res.download(path, [filename], [fn])
Transfer the file at path
as an “attachment”,
typically browsers will prompt the user for download. The
Content-Disposition “filename=” parameter, aka the one
that will appear in the brower dialog is set to path
by default, however you may provide an override filename
.
When an error has ocurred or transfer is complete the optional
callback fn
is invoked. This method uses res.sendfile()
to transfer the file.
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
}
});
res.links(links)
Join the given links
to populate the “Link” response header field.
res.links({
next: 'http://api.example.com/users?page=2',
last: 'http://api.example.com/users?page=5'
});
p yields:
Link: <http://api.example.com/users?page=2>; rel="next",
<http://api.example.com/users?page=5>; rel="last"
res.locals
Response local variables are scoped to the request, thus only available to the view(s) rendered during that request / response cycle, if any. Otherwise this API is identical to app.locals.
This object is useful for exposing request-level information such as the request pathname, authenticated user, user settings etcetera.
app.use(function(req, res, next){
res.locals.user = req.user;
res.locals.authenticated = ! req.user.anonymous;
next();
});
res.render(view, [locals], callback)
Render a view
with a callback responding with
the rendered string. When an error occurs next(err)
is invoked internally. When a callback is provided both the possible error
and rendered string are passed, and no automated response is performed.
res.render('index', function(err, html){
// ...
});
res.render('user', { name: 'Tobi' }, function(err, html){
// ...
});
Middleware
basicAuth()
Basic Authentication middleware, populating req.user
with the username.
Simple username and password:
app.use(express.basicAuth('username', 'password'));
Callback verification:
app.use(express.basicAuth(function(user, pass){
return 'tj' == user && 'wahoo' == pass;
}));
Async callback verification, accepting fn(err, user)
,
in this case req.user
will be the user object passed.
app.use(express.basicAuth(function(user, pass, fn){
User.authenticate({ user: user, pass: pass }, fn);
}))
bodyParser()
Request body parsing middleware supporting JSON, urlencoded,
and multipart requests. This middleware is simply a wrapper
for the json()
, urlencoded()
, and
multipart()
middleware.
app.use(express.bodyParser());
// is equivalent to:
app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());
For security sake, it’s better to disable file upload if your application
doesn’t need it. To do this, use only the needed middleware, i.e. don’t use
the bodyParser
and multipart()
middleware:
app.use(express.json());
app.use(express.urlencoded());
If your application needs file upload you should set up a strategy for dealing with those files.
compress()
Compress response data with gzip / deflate. This middleware should be placed “high” within the stack to ensure all responses may be compressed.
app.use(express.logger());
app.use(express.compress());
app.use(express.methodOverride());
app.use(express.bodyParser());
cookieParser()
Parses the Cookie header field and populates req.cookies
with an object keyed by the cookie names. Optionally you may enabled
signed cookie support by passing a secret
string.
app.use(express.cookieParser());
app.use(express.cookieParser('some secret'));
cookieSession()
Provides cookie-based sessions, and populates req.session
.
This middleware takes the following options:
key
cookie name defaulting toconnect.sess
secret
prevents cookie tamperingcookie
session cookie settings, defaulting to{ path: '/', httpOnly: true, maxAge: null }
proxy
trust the reverse proxy when setting secure cookies (via “x-forwarded-proto”)
app.use(express.cookieSession());
To clear a cookie simply assign the session to null before responding:
req.session = null
csrf()
CSRF protection middleware.
By default this middleware generates a token named “_csrf”
which should be added to requests which mutate
state, within a hidden form field, query-string etc. This
token is validated against req.csrfToken()
.
The default value
function checks req.body
generated
by the bodyParser()
middleware, req.query
generated
by query()
, and the “X-CSRF-Token” header field.
This middleware requires session support, thus should be added
somewhere below session()
.
directory()
Directory serving middleware, serves the given path
.
This middleware may be paired with static()
to serve
files, providing a full-featured file browser.
app.use(express.directory('public'))
app.use(express.static('public'))
This middleware accepts the following options:
hidden
display hidden (dot) files. Defaults to false.icons
display icons. Defaults to false.filter
Apply this filter function to files. Defaults to false.