原文地址:Express 4.x API

一、express

express()方法用来创建一个 Express 应用。express() 是一个由 express 模块导出的入口(top-level)函数。

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

它有一些内置方法:

1.express.static(root, [options])

express.static 是 Express 内置的唯一一个中间件。是基于 serve-static 开发的,负责托管 Express 应用内的静态资源。

root 参数指的是静态资源文件所在的根目录。

options 对象是可选的,支持以下属性:

属性 描述 类型 默认值
dotfiles 是否对外输出文件名以点(.)开头的文件。可选值为 “allow”、“deny” 和 “ignore” String “ignore”
etag 是否启用 etag 生成 Boolean true
extensions 设置文件扩展名备份选项 Boolean false
index 发送目录索引文件,设置为 false 禁用目录索引 Mixed “index.html”
lastModified 设置 Last-Modified 头为文件在操作系统上的最后修改日期。可能值为 true 或 false Boolean true
maxAge 以毫秒或者其字符串格式设置 Cache-Control 头的 max-age 属性 Number 0
redirect 当路径为目录时,重定向至 “/” Boolean true
setHeaders 设置 HTTP 头以提供文件的函数 Function

示例:

var options = {
  dotfiles: 'ignore',
  etag: false,
  extensions: ['htm', 'html'],
  index: false,
  maxAge: '1d',
  redirect: false,
  setHeaders: function (res, path, stat) {
    res.set('x-timestamp', Date.now());
  }
}

app.use(express.static('public', options));

二、application

通常用app表示express的application,通过express()方法可以创建它。

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

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

app.listen(3000);

app的作用有:

  • 控制HTTP请求的路由(请看下面app.METHOD和app.param部分)
  • 设置中间件(请看app.route部分)
  • 生成HTML界面(请看app.render部分)
  • 注册模板引擎(请看app.engine部分)

你还可以用一些设置控制app的行为(请看application settings部分)

1.app的属性

app.locals

app.locals对象是一个js对象,它的属性为application中的一些本地变量。

app.locals.title
// => 'My App'

app.locals.email
// => 'me@myapp.com'

app.locals的属性在设置以后就存在于application的整个生命周期中,而res.locals的属性只有在request的生命周期中才是可用的。

你可以在模板中访问app.locals的属性,但是在中间件中不能访问。

app.mountpath

app.mountpath属性指子app(子app也是express的实例,通常用它协助处理请求的路由)挂载的路径模式。

var express = require('express');

var app = express(); // 主app
var admin = express(); // 子app

admin.get('/', function (req, res) {
  console.log(admin.mountpath); // 输出/admin
  res.send('Admin Homepage');
})

app.use('/admin', admin); // 挂载子app

其类似于req对象的baseUrl属性,只是req的baseUrl返回URL路径,而app.mountpath返回匹配的模式。

如果子app被挂载了多个路径模式,那么app.mountpath会返回挂载路径模式的列表:

var admin = express();

admin.get('/', function (req, res) {
  console.log(admin.mountpath); // 输出[ '/adm*n', '/manager' ]
  res.send('Admin Homepage');
})

var secret = express();
secret.get('/', function (req, res) {
  console.log(secret.mountpath); // 输出/secr*t
  res.send('Admin Secret');
});

admin.use('/secr*t', secret); // 在admin下,为/secr*t加载“secret”为路由
app.use(['/adm*n', '/manager'], admin); // 在顶层app下,为'/adm*n'和'/manager'加载“admin”为路由

2.app的事件

app.on(‘mount’, callback(parent))

当子app被挂载在父app下时会触发“mount”事件,父app会被传入回调方法。

var admin = express();

admin.on('mount', function (parent) {
  console.log('Admin Mounted');
  console.log(parent); // refers to the parent app
});

admin.get('/', function (req, res) {
  res.send('Admin Homepage');
});

app.use('/admin', admin);

3.app的方法

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

这个方法跟app的其他方法类似,只是会匹配所有的HTTP请求。

它通常用来设置全局逻辑,例如,在下面的示例中,将一个all方法定义在其他路由之前,将会要求所有的请求都通过验证,并加载“user”。注意,你设置的回调方法可以不是终结点,如,loadUser回调可以完成指定的任务,然后调用next()方法将请求交给后面的路由。

app.all('*', requireAuthentication, loadUser);
// 等同于
app.all('*', requireAuthentication)
app.all('*', loadUser);

当然,你也可以将全局逻辑限制在某个地址中,如下:

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

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

HTTP的delete请求会被传递到此方法。

你可以设置多个回调方法,它们会依次执行,除非调用了next(‘route’)方法。

app.disable(name)

将name指定的设置项设置为false。app.disable(‘foo’)相当于app.set(‘foo’, false)

app.disabled(name)

如果name指定的设置项为false,则返回true。

app.enable(name)

将name指定的设置项设置为true。app.enable(‘foo’)相当于app.set(‘foo’, true)

app.enabled(name)

如果name指定的设置项为true,则返回true。

app.engine(ext, callback)

为ext后缀的文件指定模板引擎。

各个模板引擎的调用方式可能不一样,如:

app.engine('jade', require('jade').__express);//用jade模板引擎渲染jade后缀的文件
app.engine('html', require('ejs').renderFile);//用ejs模板引擎渲染html后缀的文件

var engines = require('consolidate');
app.engine('haml', engines.haml);
app.engine('html', engines.hogan);//用consolidate模板引擎渲染haml和html后缀的文件

app.get(name)

返回name表示设置项的值。

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

处理访问path的HTTTP的get请求。

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

绑定并监听端口的连接请求。

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

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

响应指定方式的HTTP请求,如GET, PUT, POST等,方法名小写。支持的HTTP请求方法如下:

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

如果要自定义HTTP请求方法,可以用“[]”包裹,如:

app['m-search']('/', function ....

app.param([name], callback)

此方法用于为路径的参数添加回调,如’/user/12’这种路径。其中,name可以为参数的名称,也可以为一个数组,表示多个参数名称。

如果name为数组,那么express会为数组中的每个参数都注册此回调,顺序为数组的顺序。如果在回调中调用next(),那么会触发下一个参数的回调(除了最后一个参数)。对于最后一个参数,next()将会触发下一个中间件方法。

举个例子,“:user”是一个路径,你用它完成一些验证性工作,那么:

app.param('user', function(req, res, next, id) {

  // 尝试获取用户信息并保存在req的user中
  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'));
    }
  });
});

param回调仅作用于定义它时在的那个路由,而不会被挂载在此路由的app或路由继承。因此,在app定义的param回调只会被app的路由触发。

param回调的调用早于路由处理回调,而且它们在一个请求-响应循环中只会被调用一次,即使有多个路由的param匹配了它。如:

app.param('id', function (req, res, next, id) {
  console.log('CALLED ONLY ONCE');
  next();
})

app.get('/user/:id', function (req, res, next) {
  console.log('although this matches');
  next();
});

app.get('/user/:id', function (req, res) {
  console.log('and this matches too');
  res.end();
});

用get方法访问/user/42,会输出:

CALLED ONLY ONCE
although this matches
and this matches too

另外一个例子,使用了数组作为name参数:

app.param(['id', 'page'], function (req, res, next, value) {
  console.log('CALLED ONLY ONCE with', value);
  next();
})

app.get('/user/:id/:page', function (req, res, next) {
  console.log('although this matches');
  next();
});

app.get('/user/:id/:page', function (req, res) {
  console.log('and this matches too');
  res.end();
});

用get方法访问/user/42/3,会输出:

CALLED ONLY ONCE with 42
CALLED ONLY ONCE with 3
although this matches
and this matches too

ps:有个方法app.param(callback)可以接受所有的参数,但是在v4.11.0弃用了,这里不做介绍,需要的可以自己找资料

app.path()

返回app的地址,string格式。

var app = express()
  , blog = express()
  , blogAdmin = express();

app.use('/blog', blog);
blog.use('/admin', blogAdmin);

console.log(app.path()); // ''
console.log(blog.path()); // '/blog'
console.log(blogAdmin.path()); // '/blog/admin'

注意,如果挂载了很多其他路由的话,此方法返回的路径可能会很复杂,所以推荐使用req.baseUrl来获取路径。

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

处理HTTP的post请求

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

处理HTTP的put请求

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

在回调中返回渲染完成的html界面。它支持传入模板对应的参数,它类似于res.render(),只是不能向客户端直接返回渲染后的界面。

app.route(path)

此方法返回一个route对象,你可以为它添加中间件以处理HTTP请求。使用此方法可以避免多余的路由名称。

var app = express();

app.route('/events')
.all(function(req, res, next) {
  // runs for all HTTP verbs first
  // think of it as route specific middleware!
})
.get(function(req, res, next) {
  res.json(...);
})
.post(function(req, res, next) {
  // maybe add a new event...
})

app.set(name, value)

为name设置value,其中name为app设置表中的某个属性。

如果name为下表中的一个,那么它会影响app的行为:

属性名 类型 描述 默认值
case sensitive routing Boolean 是否大小写敏感 默认为false,即视”/Foo”与”/foo”为同一个path
env String 环境模式 默认为process.env.NODE_ENV,或者“development”
etag Varied 设置ETag响应的头信息。可用的值请看etag选项表部分
jsonp callback name String 指定默认的jsonp回调名称 默认为”?callback=”
json replacer String json replacer回调 默认为null
json spaces Number 设置后会用指定数量的空格填充json 默认为Disabled
query parser String 指定查询解析器,可用的有“simple”或“extended”。simple表示使用node的查询解析器:querystring;extended表示使用qs 默认为”extended”
strict routing Boolean 是否使用严格路由 默认为false,路由器会将”/foo”与”/foo/”视为同一个路径
subdomain offset Number The number of dot-separated parts of the host to remove to access subdomain 2
trust proxy Varied 是否启用代理判断 Disabled.
views String or Array 表示应用的view文件存放的地址。如果是一个数组,那么将按照数组顺序寻找view文件 process.cwd() + ‘/views’
view cache Boolean 是否启用view模板缓存 生产环境默认为true
view engine String 指定view渲染引擎
x-powered-by Boolean 在HTTP头中加入”X-Powered-By: Express” true

trust proxy可选设置项:

类型
Boolean 如果为true,那么express会从X-Forwarded-*头的最左边寻找客户端的IP地址。如果为false,那么express会从req.connection.remoteAddress获取客户端的IP地址。默认为false
IP addresses 指定信任的ip地址或子网地址或ip地址数组。默认的子网名称有:
loopback - 127.0.0.1/8, ::1/128linklocal - 169.254.0.0/16, fe80::/10
uniquelocal - 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7
Number 信任前n个代理服务器
Function 定制化信任机制

etag可选设置项:

类型
Boolean true表示启用弱ETag,false表示不启用ETag。默认为true
String “strong”表示启用强ETag,“weak”表示启用弱ETag
Function 定制化ETag方法

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

为path挂载中间件,如果未指定path,默认为“/”。

通过此方法设置的路由会匹配path下所有的路径,如, app.use(‘/apple’, …)可以匹配到“/apple”, “/apple/images”, “/apple/images/news”等。

中间件中的req.originalUrl是req.baseUrl和req.path的结合,如下例:

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

中间件方法是顺序执行的,因此中间件声明的顺序很重要:

// 这个中间件会拦截所有请求
app.use(function(req, res, next) {
  res.send('Hello World');
})

// 请求到不了下面的中间件
app.get('/', function (req, res) {
  res.send('Welcome');
})

app.use的path属性可以是一个路径,或者一个路径表达式,或者正则表达式,或者一组前面这些元素的组合。下面是一些例子:

  • 路径
// 匹配/abcd开头的路径
app.use('/abcd', function (req, res, next) {
  next();
})
  • 路径表达式
// 匹配/abcd和/abd
app.use('/abc?d', function (req, res, next) {
  next();
})

// 匹配/abcd, /abbcd, /abbbbbcd等
app.use('/ab+cd', function (req, res, next) {
  next();
})

// 匹配/abcd, /abxcd, /abFOOcd, /abbArcd等
app.use('/ab\*cd', function (req, res, next) {
  next();
})

// 匹配/ad和/abcd
app.use('/a(bc)?d', function (req, res, next) {
  next();
})
  • 正则表达式
// 匹配/abc和/xyz
app.use(/\/abc|\/xyz/, function (req, res, next) {
  next();
})
  • 数组
// 匹配/abcd, /xyza, /lmn, 和 /pqr
app.use(['/abcd', '/xyza', /\/lmn|\/pqr/], function (req, res, next) {
  next();
})

app.use的function属性可以是一个中间件方法,或者一组中间件方法,或者中间件方法的数组,或者前面这些元素的组合。你可以使用实现了中间件接口的router和app作为中间件方法。

  • 单独的中间件
app.use(function (req, res, next) {
  next();
})
//或者
var router = express.Router();
router.get('/', function (req, res, next) {
  next();
})
app.use(router);
//或者
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);

三、request

req对象表示HTTP请求,包含请求的查询string、参数、body、头信息等。req对象的引用通常名为“req”,当然你也可以修改为其他名称,如:

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

但是推荐写法为:

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

1.属性

在express 4中,req对象不再拥有req.files属性,如果你需要在req.files访问上传的文件,可以使用一些中间件,如 busboy, multer, formidable, multiparty, connect-multiparty, or pez。

req.app

这个属性指向使用本中间件的express的application实例。

req.baseUrl

表示挂载的router实例的url路径。如:

var greet = express.Router();

greet.get('/jp', function (req, res) {
  console.log(req.baseUrl); // /greet
  res.send('Konichiwa!');
});

app.use('/greet', greet); // load the router on '/greet'

req.baseUrl返回的是路径,即使你为router设置的是路径模式,它依旧返回路径(与app.mountpath不同,它返回的是路径模式)。如

app.use(['/gre+t', '/hel{2}o'], greet);

访问/greet/jp,则req.baseUrl为“/greet”;访问/hello/jp,则req.baseUrl为“/hello”。

req.body

包含请求body中的键值对。推荐使用body解析中间件处理body,如body-parser或multer。

var app = require('express')();
var bodyParser = require('body-parser');
var multer = require('multer'); 

app.use(bodyParser.json()); // 解析application/json
app.use(bodyParser.urlencoded({ extended: true })); // 解析application/x-www-form-urlencoded
app.use(multer()); // 解析multipart/form-data

app.post('/', function (req, res) {
  console.log(req.body);
  res.json(req.body);
})

req.cookies

如果你使用了cookie-parser中间件,这个属性就表示request的cookie信息。如果request没有cookie,那么为{};

// Cookie: name=tj
req.cookies.name
// => "tj"

req.fresh

表示request是否是“fresh”,与req.stale相反。

如果cache-control请求的头信息没有设置为“no-cache”,那么返回true。如果是以下情况,返回的也是true:

  • 请求头信息指定了if-modified-since,并且请求头的last-modified等于或早于响应头信息的modified。
  • 请求头的if-none-match为“*”。
  • 请求头的if-none-match在解析后与响应的头信息的etag不匹配。

req.hostname

返回HTTP头信息“Host”部分的主机名称。

// Host: "example.com:3000"
req.hostname
// => "example.com"

req.ip

返回request的IP地址。如果启用了trust proxy,那么返回request的代理的地址。

req.ips

如果启用了trust proxy,那么返回请求头的“X-Forwarded-For”指定的IP地址数组。否则返回空数组。

例如,如果“X-Forwarded-For”为“client, proxy1, proxy2”,那么req.ips就为[“client”, “proxy1”, “proxy2”],其中proxy2表示下游地址。

req.originalUrl

返回完整url

req.params

返回路由匹配规则的一些参数组成的对象。如,路由规则为“/user/:name”,则通过req.params.name可以访问到name属性。

如果用正则表达式定义路由,那么参数会通过req.params[n]的形式返回,如,路由规则为“/file/*”,那么访问“/file/javascripts/jquery.js”时,req.params[0]为“javascripts/jquery.js”。

req.path

返回请求url的path部分。如“example.com/users?sort=desc”返回“users”。

req.protocol

返回请求协议,如“http”、“https”。

req.query

返回路由的查询参数组成的对象。如果没有查询参数,则返回{}。

// 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.route

返回当前匹配的路由。如:

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

那么console输出的信息(节选)为:

{
    path: '/user/: id?',
    stack: [{
        handle: [Function: userIdHandler],
        name: 'userIdHandler',
        params: undefined,
        path: undefined,
        keys: [],
        regexp: /^\/?$/i,
        method: 'get'
    }],
    methods: {
        get: true
    }
}

req.secure

判断连接类型。等同于:

'https' == req.protocol;

req.signedCookies

如果你使用了cookie-parser中间件,那么此属性会返回请求的签过名的cookies,验证签名并等待被使用。注意,对cookies签名不会隐藏它,或者对它加密,而是简单的防篡改。如果请求中没有签过名的cookie,那么返回{}。

req.stale

表示请求是否是“stale”,与req.fresh相反。

req.subdomains

返回请求的域名的子域数组。

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

req.xhr

布尔值,如果为true,表示请求的头信息中“X-Requested-With”为“XMLHttpRequest”。

2.方法

req.accepts(types)

根据请求的头信息的Accept字段,检查是否符合type的类型。这个方法会返回最佳匹配,如果没有可接受的类型,那么返回undefined(此时应该响应406 “Not Acceptable”)。

// 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']);
// => "json"

req.acceptsCharsets(charset[, …])

根据请求的头信息的Accept-Charset字段,返回指定字符集中符合要求的第一个字符。如果没有找到对应的字符,返回false。

req.acceptsEncodings(encoding [, …])

根据请求的头信息的Accept-Encoding字段,返回指定编码集中符合要求的第一个编码。如果没有找到对应的编码,返回false。

req.acceptsLanguages(lang [, …])

根据请求的头信息的Accept-Language字段,返回指定语言集中符合要求的第一个语言。如果没有找到对应的语言,返回false。

req.get(field)

返回field指定的HTTP请求头的域。

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

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

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

req.is(type)

表示HTTP请求的头信息的“Content-Type”是否符合指定的MIME类型。

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

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

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

req.param(name [, defaultValue])

已弃用

四、response

express中通常res即为HTTP的response对象。

1.属性

res.app

指向使用本中间件的express的application的实例。

res.headersSent

布尔值,表示res是否发送了头信息。

res.locals

res的局部变量组成的对象。

2.方法

res.append(field [, value])

Express v4.11.0以上才可以使用此方法

向HTTP响应的头中添加值。如果还没生成头信息,那么它会用指定的值创建头信息。value参数可以是string或者数组。

注意:在res.append之后调用res.set将会重置之前设置的头信息。

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

res.attachment([filename])

将HTTP响应的头信息的“Content-Disposition”设置为“attachment”。如果指定了filename,那么会根据文件后缀设置Content-Type,并将Content-Disposition设置为“filename=parameter”。

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

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

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

设置cookie信息,options是一个对象,其可用属性如下:

Property Type Description
domain String cookie的域名信息,默认为app的域名
expires Date cookie失效时间。如果未指定或设为0,创建session cookie
httpOnly Boolean 使cookie只能被web服务器访问
maxAge String 根据当前时间设置的超时,单位为毫秒
path String cookie的路径,默认为“/”
secure Boolean 标记是否此cookie只用于HTTPS
signed Boolean 表示此cookie是否需要签名

例如:

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

maxAge是设置失效时间的简便方法,下面的两行代码是等价的:

res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });

res.clearCookie(name [, options])

清除name指定的cookie信息,options的具体信息请看res.cookie(name, value [, options])部分

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

通过“attachment”的形式传输path指定的文件,通常,这个时候浏览器会显示下载提示。默认情况下,头信息的Content-Disposition会被设置为path,你也可以通过filename指定。

当下载发生错误或下载完成时,fn指定的方法会被调用。res.download方法需要调用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, but keep in mind the response may be partially-sent
    // so check res.headersSent
  } else {
    // decrement a download credit, etc.
  }
});

res.end([data] [, encoding])

结束响应。

res.end();
//或
res.status(404).end();

res.format(object)

此方法会调用req.accepts()为请求选择处理方法,如果req没指定头信息,那么会调用第一个方法,如果有头信息但是未找到匹配的accept,那么会返回406 “Not Acceptable”(如果设置了“default”回调,那么会调用“default”方法)。

如果有方法被调用,那么响应的Content-Type会被设置为相应的类型,你可以通过res.set()或res.type()方法修改它。

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

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

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

  'default': function() {
    // log the request and respond with 406
    res.status(406).send('Not Acceptable');
  }
});

res.get(field)

返回HTTP响应的头信息的filed对应的域。大小写不敏感。

res.json([body])

返回一个json信息。

res.jsonp([body])

返回支持jsonp的json响应。

默认情况下,jsonp的回调名称为callback,你可以通过“jsonp callback name”修改回调名称。

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

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

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

将links添加到response的HTTP头中

res.location(path)

设置响应的HTTP头的Location

res.redirect([status,] path)

重定向到path指定的地址,如果你没有指定status,那么默认为“302 Found”。

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

redirect支持基于host名称的相对路径。例如,当前地址为http://example.com/admin/post/new,那么使用res.redirect(‘/admin’)会重定向到http://example.com/admin

redirect支持基于当前路径的相对路径。例如,当前地址为http://example.com/blog/admin/(注意,地址的结尾为“/”),那么使用res.redirect(‘post/new’)会重定向到http://example.com/blog/admin/post/new。但是,如果当前路径结尾不是“/”,那么将重定向到另外一个地址。

例如,当前地址为http://example.com/blog/admin,那么使用res.redirect(‘post/new’)会重定向到http://example.com/blog/post/new

redirect支持“..”,当前地址为http://example.com/admin/post/new,那么使用res.redirect(‘..’)会重定向到http//example.com/admin/post

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

渲染view,并返回渲染后的HTML。可选参数:

  • locals。定义了view的本地变量的对象
  • callback。此方法返回error或string,如果发生error,那么内部会调用next(err)。

res.send([body])

发送HTTP响应。body可以是Buffer或String或对象或数组。

此方法会自动添加响应头的Content-Length域(除非你自己定义了),并且自动更新头信息和cache。

如果body传入的是Buffer,那么响应头的Content-Type将被设置为“application/octet-stream”,除非你如下设置:

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

如果body传入的是String,那么响应头的Content-Type将被设置为“text/html”:

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

如果body传入的是Array或Object,那么express会将其转为json。

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

res.sendFile()从 v4.8.0开始支持

传输path指定的文件,并将Content-Type设置为文件的后缀。如果没有在options添加root属性,那么path必须为文件的绝对路径。

options支持的属性如下:

属性 描述 默认值 可用版本
maxAge 设置头信息中Cache-Control的max-age属性,单位为毫秒 0
root 文件定位的相对根目录
lastModified 在头信息的Last-Modified添加文件的最后修改时间,设置为false可以关闭 Enabled 4.9.0+
headers HTTP头信息
dotfiles 是否允许传输“.”开头的文件,可选值为“allow”, “deny”, “ignore”. “ignore”

当传输完成或发生异常时,express会调用fn(err)。如果你指定了fn方法,并且发生了异常,那么你必须在此方法中结束此次request-response流程或者将控制器传递给下一个路由。

app.get('/file/:name', function (req, res, next) {

  var options = {
    root: __dirname + '/public/',
    dotfiles: 'deny',
    headers: {
        'x-timestamp': Date.now(),
        'x-sent': true
    }
  };

  var fileName = req.params.name;
  res.sendFile(fileName, options, function (err) {
    if (err) {
      console.log(err);
      res.status(err.status).end();
    }
    else {
      console.log('Sent:', fileName);
    }
  });

})

res.sendStatus(statusCode)

设置响应的HTTP状态码,并发送相应的string类型的body。

res.sendStatus(200); // equivalent to res.status(200).send('OK')
res.sendStatus(403); // equivalent to res.status(403).send('Forbidden')
res.sendStatus(404); // equivalent to res.status(404).send('Not Found')
res.sendStatus(500); // equivalent to res.status(500).send('Internal Server Error')

如果statusCode为自定义状态码,那么:

res.sendStatus(2000); // equivalent to res.status(2000).send('2000')

res.set(field [, value])

设置响应的头信息,支持传入对象。

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

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

res.status(code)

设置响应状态码。

res.status(403).end();
res.status(400).send('Bad Request');
res.status(404).sendFile('/absolute/path/to/404.png');

res.type(type)

根据type寻找合适的MIME类型,并将其设置为Content-Type。如果type中包含“/”,那么会将Content-Type直接设置为type。

res.type('.html');              // => 'text/html'
res.type('html');               // => 'text/html'
res.type('json');               // => 'application/json'
res.type('application/json');   // => 'application/json'
res.type('png');                // => image/png:

res.vary(field)

添加响应头的Vary部分

五、路由

router对象可以视为中间件及路由,用于执行中间件和路由方法,每个express应用都有一个内置的router。

router的行为类似于中间件,所以你可以将他添加在app.use或其他router的use方法中。

最上级的express对象的Router()方法可以创建router对象。

1.创建router

你可以用以下方式创建router:

var router = express.Router([options]);

options支持以下属性:

属性 描述 默认值 可用性
caseSensitive 设置大小写敏感 默认为不启用,“/Foo”和“/foo”有同样的行为
mergeParams 维护上层router的req.params。如果上层router与本router的param名称冲突,那么优先使用本router的值 false 4.5.0+
strict 设置严格路由模式 默认为不启用,“/foo”“/foo/”被视为同一个router

你可以为router添加中间件或HTTP方法路由,如下:

router.use(function(req, res, next) {
  next();
});

router.get('/events', function(req, res, next) {
  // ..
});

你可以为某个路径分配单独的router,以优化代码结构:

app.use('/calendar', router);

2.方法

router.all(path, [callback, …] callback)

类似app.all

router.METHOD(path, [callback, …] callback)

类似app.METHOD

router.param([name,] callback)

类似app.param

router.route(path)

类似app.route

router.use([path], [function, …] function)

类似app.use

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐