路由配置
Express框架中的路由用来匹配HTTP请求方法和路径,并将请求交给对应的处理函数进行处理和响应,这篇笔记我们学习Express框架中路由的用法。
创建Express路由
Express中,创建路由有两种方式,直接使用express对象创建路由,或是使用router中间件,实际开发中,我们通常选择第二种,这种方式更利于我们拆分代码,此外将路由单独抽离成一个中间件,也更利于我们对于应用中所有中间件在处理优先级上的定制安排。下面例子代码演示了这种方式创建路由的代码。
const express = require('express');
const router = express.Router();
const app = express();
router.get('/', (req, res) => {
res.send('Hello, world!');
});
app.use(router);
app.listen(8080, () => {
console.log('Express server listen on 8080');
});
代码中,我们创建了匹配GET /路径的路由。
路由匹配
Express路由使用了path-to-regexp实现路由,它支持最常用的精确匹配和一些简单的通配符,也对Restful风格的路径参数进行了支持。此外,Express也支持正则表达式匹配方式。对于常规的路由,如果不清楚具体的通配符如何使用,我们可以使用这个网页工具对我们的路由字符串进行测试:express-route-tester
基础路由匹配
下面我们展示一些Express基础路由的写法。
router.get('/', (req, res, next) => {
res.status(200).send('Match /');
});
router.get('/zh-cn/about', (req, res, next) => {
res.status(200).send('Match /zh-cn/about');
});
router.get('/data.txt', (req, res, next) => {
res.status(200).send('Match /data.txt');
});
上面3种是最常用的精确匹配模式,Express会准确匹配路由字符串并交给对应的处理函数进行处理。
router.get('/ab*cd', (req, res, next) => {
res.status(200).send('Match /abcd /abxcd /abxyzcd ...');
});
路由中的*通配符表示通配符所在位置可以是任意内容,也可以为空。它可以实现前缀或后缀的通配符匹配,这种方式也比较常用,比如/*、/*.do等。
router.get('/ab?cd', (req, res, next) => {
res.status(200).send('Match /acd /abcd');
});
router.get('/ab(cd)?e', (req, res, next) => {
res.status(200).send('Match /abe /abcde ...');
});
路由中的?通配符表示前一个字符或括号包含的内容可能不存在。
router.get('/ab+cd', (req, res, next) => {
res.status(200).send('Match /abcd /abbcd /abbbcd ...');
});
路由中的+通配符表示前一个字符包含的内容可能存在重复1次或多次,+通配符不支持括号。
上述路由中,如果使用通配符,并出现同一个请求路径可以被多个路由匹配的情况,此时会按照定义路由的顺序从上到下进行匹配,前面的路由匹配后就不会再执行后面的路由了。
Restful路径参数路由
Express路由中使用:符号表示一个路径参数,下面是一个例子。
router.get('/student/:studentId', (req, res, next) => {
res.status(200).send('Student ID [' + req.params.studentId + ']');
});
上面代码可以匹配/student/1,并将对应的路径参数解析后传入处理函数,而不能匹配/student。
正则表达式路由匹配
实际上Express的基础路由功能已经十分强大了,不过Express还是支持正则表达式路由,这里我们简单学习一下。
router.get(/.*fly$/, (req, res, next) => {
res.status(200).send('Match');
});
例子中,我们使用了正则表达式/.*fly$/,因此这条路由能够匹配例如/butterfly、/dragonfly等,不能匹配例如/flyaaa等。
HTTP方法
Express支持HTTP协议的所有方法,常用的有GET、POST、PUT、DELETE等,这些HTTP方法对应路由的函数名。下面例子代码中,我们针对GET /和POST /两种请求方法进行了不同的响应处理。
const express = require('express');
const router = express.Router();
const app = express();
router.get('/', (req, res) => {
res.send('这是GET方法');
});
router.post('/', (req, res) => {
res.send('这是POST方法');
});
app.use(router);
app.listen(8080, () => {
console.log('Express server listen on 8080');
});
代码中,虽然两条路由匹配的都是/路径,但它们匹配不同的HTTP请求方法,因此不会相互冲突。