Express.js中文文档-Router对象

 2016年03月15日    1779     声明


router路由器对象是一个独立的中间件和路由实例。你可以把它想象成一个“迷你应用程序”,只能够执行中间件和路由功能。每个Express应用都有一个内置的应用路由器。


  1. Router对象
  2. 方法

1. Router对象

路由器的行为表现本身就像一个中间件,所以你可以使用它做为参数传递给app.use()或做为参数传递给另一个器由器的use()方法。

Exress顶层对象有个Router()方法,这是一个构造函数,可以创建一个新的router(路由器对象实例)。

var express = require('express');
var router = express.Router();

router对象创建后,就可以像应用一样添加中间件和HTTP方法(get、put、post等)了。

// 所有请求都会传递给该路由
router.use(function(req, res, next) {
  // 业务逻辑,类似一个中间件
  next();
});

// 捕获 /events 路径的 GET 请求
router.get('/events', function(req, res, next) {
  // ..
});

你可以使用use()方法将路由器添加到一个特殊的根网址,这样你就可以把你的路由分为不同的文件甚至小型应用。

// 只有请求 /calendar/* 才会被发送到 "router"处理
app.use('/calendar', router);


2. 方法

2.1 创建路由:router.all()

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

类似app.all()方法,将匹配所有HTTP方法。

这个方法可以用映射“全局的”逻辑处理,可以匹配具体路径或任意的前缀。

我们可以把all处理定义的路由放在其它路由的顶部,用户所有请求都会经过这个路径,我们可以在这个路由处理器中进行用户验证和0加载用户信息信息等处理。

router.all('*', requireAuthentication, loadUser);

也可以分开写:

router.all('*', requireAuthentication)
router.all('*', loadUser);

我们也可以匹配部分路径,并添加“全局”处理。如,对'/api'开头路径进行用户验证:

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


2.2 创建指定HTTP方法的路由:router.METHOD()

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

router.METHOD()是Express提供的路由功能,METHOD是HTTP方法如:GET、PUT、POST等的小写形式,对应的路由方法分别为router.get()router.put()router.post()等,Express支持的路由方法有:Express支持的路由方式

注意:在定义路由回调函数时,我们可以像定义中间件一样,定义多个回调函数。可以通过next()进入下一个回调函数,也可以通过next('route')方法跳过后面的回调函数。

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

router.METHOD()同样支持正则表达式:

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


2.3 定义参数触发器:router.param()

router.param(name, callback)

添加路由参数的参数触发器,name表示路由参数,callback表示触发器回调函数,其形式为:

  • reqrequest对象
  • resresponse对象
  • next,定向到定一个处理(路由或中间件)

app.param()一样,自Expressv4.11.0以后,增加了router.param(name, callback)形式的触发器。

var express = require('express');
var app = express();
var router = express.Router();

// 自定义 router.param() 处理器
router.param(function(param, option) {
  return function (req, res, next, val) {
    if (val == option) {
      next();
    }
    else {
      res.sendStatus(403);
    }
  }
});

// 使用自定义的 router.param()
router.param('id', 1337);

// 捕获路由触发器
router.get('/user/:id', function (req, res) {
  res.send('OK');
});

app.use(router);

app.listen(3000, function () {
  console.log('Ready');
});


2.4 返回路由单例:router.route()

router.route(path)

返回一个单一路径的实例,然后我们就可以在其中间件中处理HTTP行为。使用app.route()可以避免路由重复定义而导致错误不易定位的问题。

var router = express.Router();

router.param('user_id', function(req, res, next, id) {
  // sample user, would actually fetch from DB, etc...
  req.user = {
    id: id,
    name: 'TJ'
  };
  next();
});

router.route('/users/:user_id')
.all(function(req, res, next) {
  // runs for all HTTP verbs first
  // think of it as route specific middleware!
  next();
})
.get(function(req, res, next) {
  res.json(req.user);
})
.put(function(req, res, next) {
  // just an example of maybe updating the user
  req.user.name = req.params.name;
  // save user ... etc
  res.json(req.user);
})
.post(function(req, res, next) {
  next(new Error('not implemented'));
})
.delete(function(req, res, next) {
  next(new Error('not implemented'));
});


2.5 挂载中间件:router.use()

router.use([path], [function, ...] function)
  • path:{String},可选参数。挂中间件的路径
  • function:{Function}。中间件函数,可以是多个

向指定路径path添加指定的中间件(s)。如果不指定path参数,默认为'/'

这个方法与app.use()方法类似。

中间件就像一个请求管道(pipe),会从请求的第一个中间件开始,依次向下传递到每一个可匹配的路径。

var express = require('express');
var app = express();
var router = express.Router();

// 一个简单的日志打印中间件,所有的请求首先会经过这个中间件
router.use(function(req, res, next) {
  console.log('%s %s %s', req.method, req.url, req.path);
  next();
});

// 这个中间件只会匹配到'/bar'开头的路径
router.use('/bar', function(req, res, next) {
  // ... /bar 下的一些逻辑处理 ...
  next();
});

// 总会被调用
router.use(function(req, res, next) {
  res.send('Hello World');
});

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

app.listen(3000);

“挂载”的中间件和路径功能是分离的,路径对于中间件来说是不可见的。这个方法的主要作用时,挂载中间件而不需要修改代码,也不需要考虑“前缀”是什么。

中间件的安装(挂载)顺序非常重要,这决定了中间件的调用顺序。

var logger = require('morgan');

router.use(logger());
router.use(express.static(__dirname + '/public'));
router.use(function(req, res){
  res.send('Hello');
});

注意:虽然中间件的功能是通过路由处理器添加的,它们运行时确是关联到了添加它的路径上(非路由处理器)。这样,中间件虽然这个路由器添回,确可能运行在另一个路由器匹配到的路径上。

var authRouter = express.Router();
var openRouter = express.Router();

authRouter.use(require('./authenticate').basic(usersdb));

authRouter.get('/:user_id/edit', function(req, res, next) { 
  // ... Edit user UI ...  
});
openRouter.get('/', function(req, res, next) { 
  // ... List users ... 
})
openRouter.get('/:user_id', function(req, res, next) { 
  // ... View user ... 
})

app.use('/users', authRouter);
app.use('/users', openRouter);