@DuanPengfei
2015-04-13T01:08:20.000000Z
字数 4198
阅读 1230
路由是指定义在程序中得终点(URI)和这个终点怎样来响应客户端的请求。
一个路由由 URI、HTTP 请求方法(GET,POST,……)组成,并且有一个或多个对终点的操作。它有如下的结构 app.METHOD(path, [callback...], [calssback...])
,这里的 app
是一个 express 实例,METHOD
是 HTTP 请求,path
对应服务器上得路径,callback
是当路由匹配时要执行的方法。
下面是一个非常基础的路由的例子。
var express = require('express');
var app = express();
// 当有一个对根目录的 GET 请求发生时返回 'hello world'
app.get('/', function(req, res) {
res.send('hello world');
});
路由方法来源于 HTTP 方法,并附加到 express 实例上。
下面定义在根目录下的 GET 和 POST 方法的例子。
// GET 方法路由
app.get('/', function (req, res) {
res.send('GET request to the homepage');
});
// POST 方法路由
app.post('/', function (req, res) {
res.send('POST request to the homepage');
});
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"
时被执行。
app.all('/secret', function (req, res, next) {
console.log('Accessing the secret section ...');
next(); // pass control to the next handler
});
路由路径,与路由方法结合,定义对于哪种请求的终点能被生成。它们可以是字符串,字符串模式,或正则表达式。
Express 以正则表达式匹配的路由路径;请阅读它的文档中定义路由的所有坑能方式。快速路由测试仪是一种方便的工具,用于测试基本的 Express 路由,虽然它不支持模式匹配。
注意
查询字符串不是路由路径的一部分。
基于字符串的路由路径例子
// 匹配对根目录的请求
app.get('/', function (req, res) {
res.send('root');
});
// 匹配对 /about 的请求
app.get('/about', function (req, res) {
res.send('about');
});
// 匹配对 /random.text 的请求
app.get('/random.text', function (req, res) {
res.send('random.text');
});
基于字符串模式的路由路径例子
// 匹配 acd 和 abcd
app.get('/ab?cd', function(req, res) {
res.send('ab?cd');
});
// 匹配 abcd, abbcd, abbbcd 等等
app.get('/ab+cd', function(req, res) {
res.send('ab+cd');
});
// 匹配 abcd, abxcd, abRABDOMcd, ab123cd 等等
app.get('/ab*cd', function(req, res) {
res.send('ab*cd');
});
// 匹配 /abe 和 /abcde
app.get('/ab(cd)?e', function(req, res) {
res.send('ab(cd)?e');
});
字符 ?,+,* 是正则表达式相对应的子集。连字符( - )和点( 。)是从字面上对基于字符串的路径进行解释。
基于正则表达式的路由路径例子
// 匹配任何包含 a 的路径
app.get(/a/, function(req, res) {
res.send('/a/');
});
// 匹配 butterfly, dragonfly; 不匹配 butterflyman, dragonfly man 等等
app.get(/.*fly$/, function(req, res) {
res.send('/.*fly$/');
});
你可以提供多个回调函数,它们就像中间件那样处理请求。唯一的例外是,这些回调可以调用 next('路径')绕过余下的路由回调。你可以利用此机制给路由增加先决条件,如果当前路由已经没有需要处理的事情,就将控制权限交给后续的路由。
一个路由处理器可以以一个函数的形式传进来,以一个数组的形式传进来,或者两者结合的形式传进来,就像下面的例子展示的那样。
单一回调函数的路由处理器
app.get('/example/a', function (req, res) {
res.send('Hello from A!');
});
多个回调函数的路由处理器( 确保指定了 next 对象 )
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!');
});
回调函数数组的路由处理器
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]);
单一回调函数和回调函数数组结合的路由处理器
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!');
});
在下面表格中的响应对象( 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('/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.Router 类用于创建模块化的可安装的路由处理程序。一个 Router 实例是一个完整的中间件和路由系统;因为这个原因,它通常被称为“小应用程序”。
下面的示例创建一个路由器作为一个模块,加载中间件,定义了一些线路,并将它安装到主应用程序上。
新建一个名为 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 中间件。