nodejs学习2:Express的路由(Route)功能

从宏观上讲,路由系统,只不过是express内部函数数组中一个函数而已(见第一篇),而且位置相对靠后。

最简单的路由系统,就是一个字典(hashmap),根据url,找的相应的处理函数即可。当然express的实现不可能那么简单。

express内部有个map,对于每一种请求方法(get,post...)都有映射,每个都映射到一个 路由对象的数组,如下图所示。

router map

实际上,每写下一个

//var app = express();
app.get('/',callback);//callback是一个函数

map的get属性就会push进一个Route,即使多次对同一个路径进行app.get。当然可以给app.get的第二个参数传一个函数的数组,下面两段代码的执行效果是一样的

//first
app.get('/',[callback1,callback2]);

//second
app.get('/',callback1);
app.get('/',callback2);

不过第一个map的get数组里,会push进1个Route(里面的callbacks有2个元素),而第二个是push进2个Route(每一个的callbacks只有一个元素),如下图

for get


express 要路由到相应的处理函数,需要method和path两个都满足条件。

1.method就是'get'、'post'等,根据这个来找到map中相应的属性

2.然后在数组中,检查path是否符合里面的Route的要求,如果符合,相应的callback函数会依次(看后面的解释)执行。callback函数的签名是:

function(req,res,next){}

如果一个callback没有结束一个请求响应的生命周期( 比如写下res.end('...') ),那么一般需要在最后写上next(),像下面那样

function(req,res,next){
    //..自己的业务逻辑
    next();
}


这样,就会继续检查下面的一个Route

如果callback中,会终结一个请求响应周期(一般也是这样),那么不应该有next(),也不会继续检查下一个Route

//一般路由函数都应该和这个类似
function(req,res,next){
    //..自己的业务逻辑
    res.end('...');//或res.render('...')等
}


试验一:多次对同一地址进行 app.get

在app.js中的 app.get('/', routes.index);上面写下:

app.get('/',function(req,res,next){
    console.log("11");
    next()
});
app.get('/',function(req,res,next){
    console.log("22");
    next()
});

那么请求主页的时候,控制台会依次输出11,22,最后执行routes.index 函数,向浏览器发送数据。

可以试着去掉上面任意一个next(),看看效果如何


用处

知道这些有什么用呢?我觉得用处不大(放学后,请不要打我-_-!)

不过还是可能有点用,比如:

很多年都没人访问我的主页,我很伤心,现在想加个功能,有人访问我的主页,就发个邮件给我,
让我开心一下。那么已有的处理主页的逻辑,不用任何改动,只需要在比较靠前的位置写:

app.get('/',function(req,res,next){
    emaiTo('[email protected]','有人访问我的主页了,喜大普奔');
    next()
});


另外一个更实际的例子可能是访问量记录

var i = 0;
app.get('*',function(req,res,next){
    console.log(++i);
    next();
});

'*' 是通配符,所以访问任何一个路径,包括

localhost:3000/
localhost:3000/nopage

i 都会自增,而且托nodejs单线程的线程模型的福,这样写就可以了。

最后,我隐约的感觉到,这样的方式,如果做AOP(面向切面编程)好像很方便(我乱说的。。),也就是说,可以在不影响已有代码的情况下,就可以加入一些功能


总结

  1. 这样看,next() 这种模型好像很常用,需要好好理解一下
  2. express的路由,先根据method 找到相应的数组,然后根据path,依次检查数组中的Route是否满足要求,并决定是否执行相应的callback函数。按照一般的写法(res.end(),res.render()),如果找到结束当前请求的指示,执行完当前代码即可,不会继续检查数组中后面的Route
  3. 从宏观上讲,路由系统,只不过是express内部函数数组中一个函数而已

知道以上几点应该就够了,后面做的一些试验,是非典型代码,玩的意味更大~~


下面是主要的试验代码,

var i = 0;
app.post('*' ,function(req,res,next){
    res.end("nothing for post");
});
app.get('*',function(req,res,next){
    console.log(++i);
    next();
});
app.get('/',function(req,res,next){
        console.log("11");
        next()
});
app.get('/',function(req,res,next){
        console.log("22");
        next()
});

//以下是建express项目后,就有的代码
app.get('/', routes.index);

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

原文地址:http://www.html-js.com/article/Nodejs-beginner-beginners-node-two-Express-routing

猜你喜欢

转载自blog.csdn.net/cen_cs/article/details/73554809