[关闭]
@DuanPengfei 2015-04-13T01:08:20.000000Z 字数 4198 阅读 1230

Express 路由

路由

路由是指定义在程序中得终点(URI)和这个终点怎样来响应客户端的请求。

一个路由由 URI、HTTP 请求方法(GET,POST,……)组成,并且有一个或多个对终点的操作。它有如下的结构 app.METHOD(path, [callback...], [calssback...]),这里的 app 是一个 express 实例,METHOD 是 HTTP 请求,path 对应服务器上得路径,callback 是当路由匹配时要执行的方法。

下面是一个非常基础的路由的例子。

  1. var express = require('express');
  2. var app = express();
  3. // 当有一个对根目录的 GET 请求发生时返回 'hello world'
  4. app.get('/', function(req, res) {
  5. res.send('hello world');
  6. });

路由方法

路由方法来源于 HTTP 方法,并附加到 express 实例上。

下面定义在根目录下的 GET 和 POST 方法的例子。

  1. // GET 方法路由
  2. app.get('/', function (req, res) {
  3. res.send('GET request to the homepage');
  4. });
  5. // POST 方法路由
  6. app.post('/', function (req, res) {
  7. res.send('POST request to the homepage');
  8. });

Express 提供以下路由方法来对应 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.

将路由方法转化为无效的 JavaScript 变量名,用括号表示法。例如:app['m-search']('/', function ...

有一个特别的路由方法 app.all(),它不来源于任何 HTTP 方法,它是用来装载一个路径对应所有请求方法的中间件。

在下面的例子中,处理器(路径后面的 function)将在无论用 GET、POST、PUT、DELETE 或者任何 HTTP 模块支持的方法请求 "/secret" 时被执行。

  1. app.all('/secret', function (req, res, next) {
  2. console.log('Accessing the secret section ...');
  3. next(); // pass control to the next handler
  4. });

路由路径

路由路径,与路由方法结合,定义对于哪种请求的终点能被生成。它们可以是字符串,字符串模式,或正则表达式。

Express 以正则表达式匹配的路由路径;请阅读它的文档中定义路由的所有坑能方式。快速路由测试仪是一种方便的工具,用于测试基本的 Express 路由,虽然它不支持模式匹配。

注意

查询字符串不是路由路径的一部分。

基于字符串的路由路径例子

  1. // 匹配对根目录的请求
  2. app.get('/', function (req, res) {
  3. res.send('root');
  4. });
  5. // 匹配对 /about 的请求
  6. app.get('/about', function (req, res) {
  7. res.send('about');
  8. });
  9. // 匹配对 /random.text 的请求
  10. app.get('/random.text', function (req, res) {
  11. res.send('random.text');
  12. });

基于字符串模式的路由路径例子

  1. // 匹配 acd 和 abcd
  2. app.get('/ab?cd', function(req, res) {
  3. res.send('ab?cd');
  4. });
  5. // 匹配 abcd, abbcd, abbbcd 等等
  6. app.get('/ab+cd', function(req, res) {
  7. res.send('ab+cd');
  8. });
  9. // 匹配 abcd, abxcd, abRABDOMcd, ab123cd 等等
  10. app.get('/ab*cd', function(req, res) {
  11. res.send('ab*cd');
  12. });
  13. // 匹配 /abe 和 /abcde
  14. app.get('/ab(cd)?e', function(req, res) {
  15. res.send('ab(cd)?e');
  16. });

字符 ?,+,* 是正则表达式相对应的子集。连字符( - )和点( 。)是从字面上对基于字符串的路径进行解释。

基于正则表达式的路由路径例子

  1. // 匹配任何包含 a 的路径
  2. app.get(/a/, function(req, res) {
  3. res.send('/a/');
  4. });
  5. // 匹配 butterfly, dragonfly; 不匹配 butterflyman, dragonfly man 等等
  6. app.get(/.*fly$/, function(req, res) {
  7. res.send('/.*fly$/');
  8. });

路由处理器

你可以提供多个回调函数,它们就像中间件那样处理请求。唯一的例外是,这些回调可以调用 next('路径')绕过余下的路由回调。你可以利用此机制给路由增加先决条件,如果当前路由已经没有需要处理的事情,就将控制权限交给后续的路由。

一个路由处理器可以以一个函数的形式传进来,以一个数组的形式传进来,或者两者结合的形式传进来,就像下面的例子展示的那样。

单一回调函数的路由处理器

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

多个回调函数的路由处理器( 确保指定了 next 对象 )

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

回调函数数组的路由处理器

  1. var cb0 = function (req, res, next) {
  2. console.log('CB0');
  3. next();
  4. }
  5. var cb1 = function (req, res, next) {
  6. console.log('CB1');
  7. next();
  8. }
  9. var cb2 = function (req, res) {
  10. res.send('Hello from C!');
  11. }
  12. app.get('/example/c', [cb0, cb1, cb2]);

单一回调函数和回调函数数组结合的路由处理器

  1. var cb0 = function (req, res, next) {
  2. console.log('CB0');
  3. next();
  4. }
  5. var cb1 = function (req, res, next) {
  6. console.log('CB1');
  7. next();
  8. }
  9. app.get('/example/d', [cb0, cb1], function (req, res, next) {
  10. console.log('response will be sent by the next function ...');
  11. next();
  12. }, function (req, res) {
  13. res.send('Hello from D!');
  14. });

响应方法

在下面表格中的响应对象( res )的方法可以给客户端返回一个响应并结束本次请求响应循环。如果在路由处理器中没有调用响应方法,那么本次客户端请求将被挂起。

方法 描述
res.download() 提供一个可下载的文件。
res.end() 结束响应进程。
res.json() 发送一个 JSON 响应。
res.jsonp() 发送带有 JSONP 支持 的 JSON 响应。
res.redirect() 重定向一个请求。
res.render() 渲染一个模板。
res.send() 发送多种格式的响应。
res.sendFile 发送一个字节流文件。
res.sendStatus() 发送状态码和状态码含义的字符串作为响应体。

app.route()

可以用 app.route 创建链式处理器的路由路径。由于路径在一个单独位置,它有助于创建模块化路线,减少冗余和错别字。有关路由的详细信息,请参阅路由器文档。

  1. app.route('/book')
  2. .get(function(req, res) {
  3. res.send('Get a random book');
  4. })
  5. .post(function(req, res) {
  6. res.send('Add a book');
  7. })
  8. .put(function(req, res) {
  9. res.send('Update the book');
  10. });

express.Router

express.Router 类用于创建模块化的可安装的路由处理程序。一个 Router 实例是一个完整的中间件和路由系统;因为这个原因,它通常被称为“小应用程序”。

下面的示例创建一个路由器作为一个模块,加载中间件,定义了一些线路,并将它安装到主应用程序上。

新建一个名为 birds.js 的文件放在程序目录下,将一下内容写入文件:

  1. var express = require('express');
  2. var router = express.Router();
  3. // 为该路由制定中间件
  4. router.use(function timeLog(req, res, next) {
  5. console.log('Time: ', Date.now());
  6. next();
  7. });
  8. // 定义根目录路由
  9. router.get('/', function(req, res) {
  10. res.send('Birds home page');
  11. });
  12. // 定义 about 页面路由
  13. router.get('/about', function(req, res) {
  14. res.send('About birds');
  15. });
  16. module.exports = router;

接下来,这主程序中加载路由模块:

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

现在该应用程序就可以响应 /birds 和 /birds/about 路径的请求了,连同一起调用在路由中定义的 timeLog 中间件。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注