express框架--路由/路由器实例

责编:menVScode 2017-08-30 10:35 阅读(850)

路由

【路由方法】

  针对不同的请求,Express提供了use方法的一些别名,这些别名是和 HTTP 请求对应的路由方法: get、post、put、head、delete、options、trace、copy、lock、mkcol、move、purge、propfind、proppatch、unlock、report、mkactivity、checkout、merge、m-search、notify、subscribe、unsubscribe、patch、search 和 connect。

  app.all() 是一个特殊的路由方法,没有任何 HTTP 方法与其对应,它的作用是对于一个路径上的所有请求加载中间件。

  有些路由方法名不是合规的 JavaScript 变量名,此时使用括号记法,比如 app['m-search']('/', function ...

var express = require("express");
var http = require("http");
var app = express();

app.all("*", function(request, response, next) {
  response.writeHead(200, { "Content-Type": "text/plain" });
  next();
});

app.get("/", function(request, response) {
  response.end("Welcome to the homepage!");
});

app.get("/about", function(request, response) {
  response.end("Welcome to the about page!");
});

app.get("*", function(request, response) {
  response.end("404!");
});

http.createServer(app).listen(1337);

        上面代码的all方法表示,所有请求都必须通过该中间件,参数中的“*”表示对所有路径有效。get方法则是只有GET动词的HTTP请求通过该中间件,它的第一个参数是请求的路径。由于get方法的回调函数没有调用next方法,所以只要有一个中间件被调用了,后面的中间件就不会再被调用了。

【路由路径】

  路由方法的第一个参数,都是请求的路径,称为路由路径,它可以是字符串、字符串模式或者正则表达式。

  1、字符串匹配

// 匹配 /about 路径的请求
app.get('/about', function (req, res) {
  res.send('about');
});

        2、字符串模式匹配

// 匹配 acd 和 abcd
app.get('/ab?cd', function(req, res) {
  res.send('ab?cd');
});

        3、正则表达式匹配

// 匹配任何路径中含有 a 的路径:
app.get(/a/, function(req, res) {
  res.send('/a/');
});

【路由句柄】

  可以为请求处理提供多个回调函数,其行为类似中间件。唯一的区别是这些回调函数可能调用 next('route') 方法而略过其他路由回调函数。可以利用该机制为路由定义前提条件,如果在现有路径上继续执行没有意义,则可将控制权交给剩下的路径。

  路由句柄有多种形式,可以是一个函数、一个函数数组,或者是两者混合。

  1、使用一个回调函数处理路由

app.get('/example/a', function (req, res) {
  res.send('Hello from A!');
});

        2、使用多个回调函数处理路由

app.get('/example/b', function (req, res, next) {
  console.log('response will be sent by the next function ...');
  next();
}, function (req, res) {
  res.send('Hello from B!');
});

        3、使用回调函数数组处理路由

var cb0 = function (req, res, next) {
  console.log('CB0');
  next();
}
var cb1 = function (req, res, next) {
  console.log('CB1');
  next();
}
var cb2 = function (req, res) {
  res.send('Hello from C!');
}
app.get('/example/c', [cb0, cb1, cb2]);

        4、混合使用函数和函数数组处理路由

var cb0 = function (req, res, next) {
  console.log('CB0');
  next();
}
var cb1 = function (req, res, next) {
  console.log('CB1');
  next();
}
app.get('/example/d', [cb0, cb1], function (req, res, next) {
  console.log('response will be sent by the next function ...');
  next();
}, function (req, res) {
  res.send('Hello from D!');
});

【链式路由句柄】

  可使用 app.route() 创建路由路径的链式路由句柄。由于路径在一个地方指定,这样做有助于创建模块化的路由,而且减少了代码冗余和拼写错误。

app.route('/book')
  .get(function(req, res) {
    res.send('Get a random book');
  })
  .post(function(req, res) {
    res.send('Add a book');
  })
  .put(function(req, res) {
    res.send('Update the book');
  });


路由器实例

  从Express 4.0开始,路由器功能成了一个单独的组件Express.Router。它好像小型的express应用程序一样,有自己的use、get、param和route方法。

  可使用 express.Router 类创建模块化、可挂载的路由句柄。Router 实例是一个完整的中间件和路由系统,因此常称其为一个“mini-app”。

【基本用法】

  首先,Express.Router是一个构造函数,调用后返回一个路由器实例。然后,使用该实例的HTTP动词方法,为不同的访问路径,指定回调函数;最后,挂载到某个路径。

var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
  res.send('首页');
});
router.get('/about', function(req, res) {
  res.send('关于');
});
app.use('/', router);

        上面代码先定义了两个访问路径,然后将它们挂载到根目录。如果最后一行改为app.use(‘/app’, router),则相当于为/app和/app/about这两个路径,指定了回调函数。

  这种路由器可以自由挂载的做法,为程序带来了更大的灵活性,既可以定义多个路由器实例,也可以为将同一个路由器实例挂载到多个路径。

【router.route方法】

  router实例对象的route方法,可以接受访问路径作为参数。

var express = require('express');
var router = express.Router();
router.route('/api')
    .post(function(req, res) {
        // ...
    })
    .get(function(req, res) {
        Bear.find(function(err, bears) {
            if (err) res.send(err);
            res.json(bears);
        });
    });
app.use('/', router);

【router中间件】

  use方法为router对象指定中间件,在数据正式发给用户之前,对数据进行处理。下面是一个中间件的例子。

router.use(function(req, res, next) {
    console.log(req.method, req.url);
    next();    
});

        上面代码中,回调函数的next参数,表示接受其他中间件的调用。函数体中的next(),表示将数据传递给下一个中间件。

  [注意]中间件放置顺序很重要,等同于执行顺序。而且,中间件必须放在HTTP动词方法之前,否则不会执行。

【对路径参数的处理】

  router对象的param方法用于路径参数的处理。

router.param('name', function(req, res, next, name) {
    // 对name进行验证或其他处理……
    console.log(name);
    req.name = name;
    next();    
});
router.get('/hello/:name', function(req, res) {
    res.send('hello ' + req.name + '!');
});

  上面代码中,get方法为访问路径指定了name参数,param方法则是对name参数进行处理。

  [注意]param方法必须放在HTTP动词方法之前。

【实例】

  下面的实例程序创建了一个路由模块,并加载了一个中间件,定义了一些路由,并且将它们挂载至应用路径上。

  在 app 目录下创建名为 birds.js 的文件,内容如下:

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

// 该路由使用的中间件
router.use(function timeLog(req, res, next) {
  console.log('Time: ', Date.now());
  next();
});
// 定义网站主页的路由
router.get('/', function(req, res) {
  res.send('Birds home page');
});
// 定义 about 页面的路由
router.get('/about', function(req, res) {
  res.send('About birds');
});

module.exports = router;

  然后在应用中加载路由模块:

var birds = require('./birds');
...
app.use('/birds', birds);

        应用即可处理发自 /birds 和 /birds/about 的请求,并且调用为该路由指定的 timeLog 中间件。

标签: express 路由 框架
前端交流群: MVC前端网(menvscode.com)-qq交流群:551903636

邮箱快速注册

忘记密码