`

NodeJS框架express的路径映射(路由)功能及控制

阅读更多

 

我们知道Express是一个基于NodeJS的非常优秀的服务端开发框架,本篇CSSer将提供express框架的route和route control章节,route实现了客户端请求的URL的路径映射功能,暂且译为路由或URL映射吧。如果你还是不太理解,相信看完本篇文章将会有些收获的。

路由(URL映射)

Express利用HTTP动作提供了有意义并富有表现力的URL映射API,例如我们可能想让用户帐号的URL看起来像“/user/12”的样子,下面的例子就能实现这样的路由,其中与占位标识符(本例为:id)相关的值可以被req.params获取到。

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

上例中当我们访问/user/12时返回“user 12”,CSSer注:app.get相当于在服务器注册了一个监听get请求事件的侦听器,当请求的URL满足第一个参数时,执行后面的回调函数,该过程是异步的。

路由是一个可以被内部编译成正则表达式的简单字符串,比如当/user/:id被编译后,被内部编译后的正则表达式字符串看起来会是下面的样子(简化后):

\/user\/([^\/]+)\/?

要实现复杂点的,我们可以传入正则表达式直接量,因为正则捕获组是匿名的因此我们可以通过req.params进行访问,第一个捕获组应该是req.params[0],第二个应该是req.params[1],以此类推。

app.get(/^\/users?(?:\/(\d+)(?:\.\.(\d+))?)?/, function(req, res){
    res.send(req.params);
});

通过Linux的curl命令来测试我们定义的路由:

$ curl http://cssercom:3000/user
[null,null]
$ curl http://cssercom:3000/users
[null,null]
$ curl http://cssercom:3000/users/1
["1",null]
$ curl http://cssercom:3000/users/1..15
["1","15"]

下面是一些路由例子,以及与之相匹配的关联路径:

"/user/:id"
/user/12

"/users/:id?"
/users/5
/users

"/files/*"
/files/jquery.js
/files/javascripts/jquery.js

"/file/*.*"
/files/jquery.js
/files/javascripts/jquery.js

"/user/:id/:operation?"
/user/1
/user/1/edit

"/products.:format"
/products.json
/products.xml

"/products.:format?"
/products.json
/products.xml
/products

"/user/:id.:format?"
/user/12
/user/12.json

另外,我们可以通过POST方式提交json数据,然后利用bodyParser中间件解析json请求体并把json数据返回给客户端:

var express = require('express')
  , app = express.createServer();

app.use(express.bodyParser());

app.post('/', function(req, res){
  res.send(req.body);
});

app.listen(3000);

通常我们所使用的占位符(比如/user/:id)都没有任何限制,即用户可以传入各种各样数据类型的id值,如果我们希望限制用户id为数字,可以这样写“/user/:id(\d+)”,这样就能保证只有该占位符数据类型为数值类型才会进行路由的相关处理。

路由控制

一个应用中可以定义多个路由,我们可以控制以令其转向下一个路由,Express提供了第三个参数即next()函数。当一个模式不被匹配时,控制将被转回Connect(Express基于Connect模块),同时中间件会继续按照它们在use()中增加的顺序来执行。当多个定义的路由都可能匹配同一个URL时也是如此,除非某个路由并不调用next()且已将响应输出到客户端,否则它们也将按顺序执行。

app.get('/users/:id?', function(req, res, next){
    var id = req.params.id;
    if (id) {
        // 一回注:如果在这里就将响应内容输出给客户端,那么后续的URL映射将不会被调用
    } else {
        next(); // 将控制转向下一个符合URL的路由
    }
});

app.get('/users', function(req, res){
    // do something else
});

app.all()方法可以对所有HTTP动作应用单一调用入口,这在有些情况下很有用。下面我们使用该功能来从我们的模拟数据库中加载一个用户,并把它分配给req.user。

var express = require('express')
  , app = express.createServer();

var users = [{ name: 'www.csser.com' }];

app.all('/user/:id/:op?', function(req, res, next){
  req.user = users[req.params.id];
  if (req.user) {
    next();
  } else {
    next(new Error('cannot find user ' + req.params.id));
  }
});

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

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

app.put('/user/:id', function(req, res){
  res.send('updating ' + req.user.name);
});

app.get('*', function(req, res){
  res.send('what???', 404);
});

app.listen(3000);

路由参数预处理

本节为后补(2011-4-16)。

路由参数预处理通过隐式的数据处理,可以大幅提高应用代码的可读性和请求URL的验证。假如你经常性的从几个路由获取通用数据,如通过/user/:id加载用户信息,通常我们可能会这样做:

app.get('/user/:userId', function(req, res, next){
  User.get(req.params.userId, function(err, user){
    if (err) return next(err);
    res.send('user ' + user.name);
  });
});

利用预处理后参数可以被映射到回调函数,从而可以提供诸如验证、强制性改变值,甚至从数据库中加载数据等功能。下面我们将调用app.param()并传入我们希望映射到某个中间件的参数,可以看到我们接收了包含占位符(:userId)值的id参数。在这里可以与平常一样进行用户数据加载以及错误处理,并能简单的通过调用next()将控制权转向下一个预处理或路由(路径控制)。

app.param('userId', function(req, res, next, id){
  User.get(id, function(err, user){
    if (err) return next(err);
    if (!user) return next(new Error('failed to find user'));
    req.user = user;
    next();
  });
});

这样做,不仅向上面提到的可以大幅提高路由的可读性,还能在整个应用中共享该部分的逻辑实现,达到复用目的。

app.get('/user/:userId', function(req, res){
  res.send('CSSer用户为 ' + req.user.name);
});

对于简单的情况如路由占位符验证和强迫改变值,只需要传入1个参数(支持1个参数),期间抛出的异常将自动传入next(err)。

app.param('number', function(n){ return parseInt(n, 10); });

也可以同时将回调函数应用到多个占位符,比如路由/commits/:from-:to来说,:from和:to都是数值类型,我们可以将它们定义为数组:

app.param(['from', 'to'], function(n){ return parseInt(n, 10); });

结语

通过本文的学习,我们应该有些感觉了,NodeJS不仅仅可以实现我们产品的服务端逻辑,同时我们还可以利用Javascript做服务器编程,注意是服务器,也就是说,我们可以利用Javascript来定制以往只能在apache中才可以做到的功能。NodeJS还需要rewrite吗?路径映射更简单更强大,还要rewrite干嘛用?

 

分享到:
评论

相关推荐

    nodeJS中express框架和mysql简单的连接demo

    这个“nodeJS中express框架和mysql简单的连接demo”项目,旨在演示如何将两者结合,实现在Web应用中与数据库进行交互,包括向数据库插入数据和查询数据。 首先,你需要确保已经安装了以下Node.js相关的依赖库: 1. ...

    vue+nodejs+express+mybatis

    这个项目案例结合了前端的Vue.js框架、后端的Node.js与Express框架,以及数据库操作的MyBatis持久层框架,构建了一个完整的Web应用程序。下面将分别详细介绍这四个技术的核心概念、用途及它们如何协同工作。 **Vue....

    NodeJS+Express+MongoDB简单博客系统

    1. **路由**:Express中的路由是URL路径和处理函数之间的映射。例如,`/blog`路由可能对应一个展示所有博客文章的函数。 2. **中间件**:Express的中间件函数是接收请求并可选择传递给下一个中间件的函数。它们常...

    nodejs+express+mysql起步学习demo:待完善.zip

    Express是一个轻量级的Web应用框架,它为Node.js提供了许多便利的功能,如路由处理、中间件系统等。MySQL则是一种广泛使用的开源关系型数据库管理系统,适用于存储和检索大量数据。 在"nodejs+express+mysql起步...

    NodeJS+express如何新建一个自己需要的项目

    Express则是Node.js的一个轻量级Web应用框架,它简化了构建Web服务的过程,使得开发者能够快速搭建功能丰富的Web应用程序。本篇文章将深入探讨如何使用Node.js和Express来创建一个自定义的项目。 1. **安装Node.js*...

    jinwei_nodejs_express

    Express基于Connect库,遵循MVC(模型-视图-控制器)设计模式,使得开发者可以快速构建功能丰富的应用程序。其主要特点包括: 1. **路由处理**:Express允许开发者通过定义路由来处理HTTP请求,如GET、POST等,实现...

    Node.js-使用nodejs的express框架搭建的后台管理系统.zip

    这个"Node.js-使用nodejs的express框架搭建的后台管理系统.zip"文件,很可能包含了一个使用Express构建的后台管理系统的源代码,我们可以从以下几个方面来探讨相关的知识点: 1. **Node.js基础**:理解Node.js的...

    nodejs + express + mongoose demo

    - Express:一个轻量级的Web应用框架,为构建Web应用提供了一系列便利功能,如路由、中间件等。 - Mongoose:MongoDB的ODM库,用于在Node.js中处理MongoDB的数据操作,提供模型和集合的概念,简化数据操作。 - Demo...

    Node.js-nodejs服务框架

    1. Express.js:Express 是最广泛使用的 Node.js 框架之一,它简化了路由定义、中间件处理和模板引擎的使用。Express 提供了一个极简的 API,使得开发者可以快速搭建 web 应用。 2. Koa.js:由 Express 的作者创建...

    nodejs+vue+express+mysql

    它提供了路由控制、请求处理和响应发送等功能,使得构建Web服务变得更加高效。 **MySQL**: MySQL是一款开源的关系型数据库管理系统,广泛应用于Web应用中。它支持SQL标准,具有高性能、可扩展性和稳定性。MySQL的...

    基于Vue+Nodejs+Express在线购物商城设计源码案例设计.zip

    1. 路由:Express中的路由定义了特定URL路径与处理函数之间的映射,用于处理不同的HTTP方法(GET、POST、PUT、DELETE等)。 2. 中间件:Express的中间件机制允许你分层处理请求,每个中间件可以读取、修改请求和响应...

    Nodejs Express 用户登录注册示例

    Express支持中间件系统,使得路由控制、请求处理和响应发送变得更加灵活。 3. **MySQL数据库**:MySQL是一个开源的关系型数据库管理系统,广泛用于Web应用程序。在这个示例中,MySQL用于存储用户注册时输入的用户名...

    基于Vue+Nodejs+Express在线购物商城设计毕业设计.zip

    这是一个基于前端Vue.js框架、后端Node.js及Express框架构建的在线购物商城的毕业设计项目。这个项目展示了如何将现代Web开发技术结合,构建一个功能完善的电子商务平台。下面,我们将详细探讨这个项目涉及的主要...

    基于Nodejs+Express+WebSocket网络在线聊天室系统设计源码.zip

    6. **路由与控制器**:在Express中,路由是定义HTTP请求与处理函数之间的映射。在这个聊天室系统中,可能有登录、注册等HTTP路由,以及WebSocket连接、发送消息等WebSocket路由。控制器负责具体的业务逻辑,如验证...

    nodejs mvc框架

    这些框架提供了丰富的功能,包括路由处理、中间件、模板引擎等,帮助开发者快速构建Web应用。本示例中提到的"n2Mvc"可能是一个自定义或未公开的MVC框架,它可能具有类似的架构和功能。 4. **Express.js**:Express...

    使用nodejs + express + angularjs + mysql 实现的自主学习与考试系统.zip

    Express是Node.js的一个框架,它简化了构建Web应用的过程,提供了路由控制、中间件系统等特性。在本系统中,Express用于定义路由,处理GET和POST请求,比如用户登录、注册、试题获取、提交答案等操作。 AngularJS是...

    基于NodeJs+Express+Mysql学生社团活动管理系统毕业源码案例设计.zip

    Express是Node.js中最受欢迎的web应用框架,它简化了构建web应用的过程,提供了路由管理、中间件系统和视图系统等功能。在本项目中,Express被用来设置API接口,处理GET、POST等HTTP请求,实现用户登录、注册、活动...

    nodejs-express

    Express 是基于 Node.js 平台的一个快速、开放、极简的 web 开发框架,它简化了构建web服务的过程,使得开发人员能够更高效地创建功能丰富的网络应用。 标题 "nodejs-express" 指的是使用 Node.js 和 Express 框架...

Global site tag (gtag.js) - Google Analytics