# 路由
# 概念
路由 定义了 请求 和 请求处理函数 之间的映射关系。路由就是挂在在特定路径的中间件.
路由是由一个 URI、HTTP 请求方法 和若干个句柄组成, 它的结构如下: p
app.METHOD(path, [callback...], callback)
- app 是 express 对象的一个实例
- METHOD 是一个 HTTP 请求方法
- path 是服务器上的路径
- callback 是当路由匹配时要执行的函数。
例子:
var express = require('express');
var app = express();
// respond with "hello world" when a GET request is made to the homepage
app.get('/', function(req, res) {
res.send('hello world');
});
# 路由路径
路由路径和请求方法一起定义了请求的端点, 它可以是字符串、字符串模式或者正则表达式。
例子:
// 使用字符串的路由路径示例:
app.get('/about', function (req, res) {
res.send('about');
});
// 使用字符串模式的路由路径示例:
app.get('/ab?cd', function(req, res) {
res.send('ab?cd');
});
// 使用正则表达式的路由路径示例:
app.get(/.*fly$/, function(req, res) {
res.send('/.*fly$/');
});
# 路由句柄
可以为请求处理提供多个回调函数. 回调函数调用 next('route')
方法可以略过其他路由回调函数。
路由句柄有多种形式,可以是一个函数、一个函数数组,或者是两者混合,如下所示.
// 使用多个回调函数处理路由(记得指定 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]);
# 响应方法
响应对象(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()
创建指定路由路径的链式路由句柄. 就是在一条语句中为一个路径, 指定在遇到不同 HTTP 方法时所需调用的对应函数.
由于路径在一个地方指定,这样做有助于创建模块化的路由
例子:
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
使用 express.Router
类可以创建模块化、可挂载的路由句柄
Router
实例是一个完整的中间件和路由系统, 将其挂载在 app 实例的路径上, 就可以将在 router 实例中定义的路由, 相对于 app 实例的路由进行使用.
因为路由的行为和中间件很像, router 实例可以作为参数传入 app 实例 或者 其它 router 实例的 use()
方法中.
例子:
下面的实例程序创建了一个路由模块,并加载了一个中间件,定义了一些路由,并且将它们挂载至应用的路径上。
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;
在应用中加载路由模块, 应用即可处理发自 /birds
和 /birds/about
的请求,并且调用为该路由指定的 timeLog 中间件。
var birds = require('./birds');
...别的代码...
app.use('/birds', birds);