您的位置:首页 > Web前端 > Node.js

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

2017-06-21 18:56 405 查看
从宏观上讲,路由系统,只不过是express内部函数数组中一个函数而已(见第一篇),而且位置相对靠后。

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

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



实际上,每写下一个

//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只有一个元素),如下图



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('xxx@xxx.com','有人访问我的主页了,喜大普奔');
next()
});



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

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


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

localhost:3000/
localhost:3000/nopage

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

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

总结

这样看,next() 这种模型好像很常用,需要好好理解一下
express的路由,先根据method 找到相应的数组,然后根据path,依次检查数组中的Route是否满足要求,并决定是否执行相应的callback函数。按照一般的写法(
res.end()
,
res.render()
),如果找到结束当前请求的指示,执行完当前代码即可,不会继续检查数组中后面的Route
从宏观上讲,路由系统,只不过是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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: