原创做者:大哼、阿干、三三、小虎、胖子、小哈、DDU、可木、晃晃
文案校对:李益、大力萌、Au、DDU、小溪里、小哈
风采主播:可木、阿干、Au、DDU、小哈
视频剪辑:小溪里
主站运营:给力xi、xty
教程主编:张利涛php
视频地址:www.cctalk.com/v/151149238…node
上一节咱们学习了中间件的基本概念,本节主要带你们学习下
koa-router
路由中间件的使用方法。git
路由是用于描述 URL
与处理函数之间的对应关系的。好比用户访问 http://localhost:3000/
,那么浏览器就会显示 index
页面的内容,若是用户访问的是 http://localhost:3000/home
,那么浏览器应该显示 home
页面的内容。github
要实现上述功能,若是不借助 koa-router
或者其余路由中间件,咱们本身去处理路由,那么写法可能以下所示:ajax
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx, next) => {
if (ctx.request.path === '/') {
ctx.response.body = '<h1>index page</h1>';
} else {
await next();
}
});
app.use(async (ctx, next) => {
if (ctx.request.path === '/home') {
ctx.response.body = '<h1>home page</h1>';
} else {
await next();
}
});
app.use(async (ctx, next) => {
if (ctx.request.path === '/404') {
ctx.response.body = '<h1>404 Not Found</h1>';
} else {
await next();
}
});
app.listen(3000, ()=>{
console.log('server is running at http://localhost:3000')
})
复制代码
把上述代码复制并覆盖到 app.js
中,而后执行如下命令启动 node
程序:正则表达式
node app.js
复制代码
启动以后在浏览器中分别访问 http://localhost:3000/
、http://localhost:3000/home
、http://localhost:3000/404
就能看到相应的页面了。npm
上述 app.js
的代码中,由 async
标记的函数称为『异步函数』,在异步函数中,能够用 await
调用另外一个异步函数,async
和 await
这两个关键字将在 ES7 中引入。参数 ctx
是由 koa
传入的,咱们能够经过它来访问 request
和 response
,next
是 koa
传入的将要处理的下一个异步函数。json
注意: 因为 node
在 v7.6.0
中才支持 async
和 await
,因此在运行 app.js
以前请确保 node 版本正确,或者使用一些第三方的 async
库来支持。小程序
这样的写法可以处理简单的应用,可是,一旦要处理的 URL
多起来的话就会显得特别笨重。因此咱们能够借助 koa-router
来更简单的实现这一功能。 下面来介绍一下如何正确的使用 koa-router
。微信小程序
经过 npm
命令直接安装:
npm i koa-router -S
复制代码
-S
或者 --save
是为了安装完成以后可以在 package.json
的 dependencies
中保留 koa-router
,以便于下次只须要执行 npm i
或者 npm install
就可以安装全部须要的依赖包。
若是要在 app.js
中使用 koa-router
来处理 URL
,能够经过如下代码来实现:
const Koa = require('koa')
// 注意 require('koa-router') 返回的是函数:
const router = require('koa-router')()
const app = new Koa()
// 添加路由
router.get('/', async (ctx, next) => {
ctx.response.body = `<h1>index page</h1>`
})
router.get('/home', async (ctx, next) => {
ctx.response.body = '<h1>HOME page</h1>'
})
router.get('/404', async (ctx, next) => {
ctx.response.body = '<h1>404 Not Found</h1>'
})
// 调用路由中间件
app.use(router.routes())
app.listen(3000, ()=>{
console.log('server is running at http://localhost:3000')
})
复制代码
运行 app.js
:
node app.js
复制代码
执行完上面的操做以后,咱们在浏览器中访问 http://localhost:3000/
:
在浏览器中访问 http://localhost:3000/home
:
在浏览器中访问 http://localhost:3000/404
:
经过上面的例子,咱们能够看到和以前不使用 koa-router
的显示效果是同样的。不过使用了 koa-router
以后,代码稍微简化了一些,并且少了 if
判断,还有省略了 await next()
(由于没有其余中间件须要执行,因此这里就先省略了)。
固然,除了 GET
方法,koa-router
也支持处理其余的请求方法,好比:
router
.get('/', async (ctx, next) => {
ctx.body = 'Hello World!';
})
.post('/users', async (ctx, next) => {
// ...
})
.put('/users/:id', async (ctx, next) => {
// ...
})
.del('/users/:id', async (ctx, next) => {
// ...
})
.all('/users/:id', async (ctx, next) => {
// ...
});
复制代码
在 HTTP
协议方法中,GET
、POST
、PUT
、DELETE
分别对应 查
,增
,改
,删
,这里 router
的方法也一一对应。一般咱们使用 GET
来查询和获取数据,使用 POST
来更新资源。PUT
和 DELETE
使用比较少,可是若是大家团队采用 RESTful架构
,就比较推荐使用了。咱们注意到,上述代码中还有一个all
方法。all
方法用于处理上述方法没法匹配的状况,或者你不肯定客户端发送的请求方法类型。
举个例子,假设客户端使用 jQuery
来开发,有以下几个 ajax
请求:
// 优先匹配和 router.get 方法中 url 规则同样的请求,若是匹配不到的话就匹配和 router.all 方法中 url 规则同样的请求。
$.ajax({
method: "GET",
url: "some.php",
data: { name: "John" }
}).done(function( msg ) {
// do something
});
// 优先匹配和 router.post 方法中 url 规则同样的请求,若是匹配不到的话就匹配和 router.all 方法中 url 规则同样的请求。
$.ajax({
method: "POST",
url: "some.php",
data: { name: "John" }
}).done(function( msg ) {
// do something
});
复制代码
上面例子中两个方法最主要的区别就是 ajax
中 method
的值,method
的值和 router
的方法一一对应。上述代码中没有处理异常,当请求都没法匹配的时候,咱们能够跳转到自定义的 404
页面,好比:
router.all('/*', async (ctx, next) => {
ctx.response.status = 404;
ctx.response.body = '<h1>404 Not Found</h1>';
});
复制代码
*
号是一种通配符,表示匹配任意 URL
。这里的返回是一种简化的写法,真实开发中,咱们确定要去读取 HTML
文件或者其余模板文件的内容,再响应请求。关于这部分的内容后面的章节中会详细介绍。
在开发过程当中咱们可以很方便的生成路由 URL
:
router.get('user', '/users/:id', function (ctx, next) {
// ...
});
router.url('user', 3);
// => 生成路由 "/users/3"
router.url('user', { id: 3 });
// => 生成路由 "/users/3"
router.use(function (ctx, next) {
// 重定向到路由名称为 “sign-in” 的页面
ctx.redirect(ctx.router.url('sign-in'));
})
复制代码
router.url
方法方便咱们在代码中根据路由名称和参数(可选)去生成具体的 URL
,而不用采用字符串拼接的方式去生成 URL
了。
koa-router
也支持单个路由多中间件的处理。经过这个特性,咱们可以为一个路由添加特殊的中间件处理。也能够把一个路由要作的事情拆分红多个步骤去实现,当路由处理函数中有异步操做时,这种写法的可读性和可维护性更高。好比下面的示例代码所示:
router.get(
'/users/:id',
function (ctx, next) {
return User.findOne(ctx.params.id).then(function(user) {
// 首先读取用户的信息,异步操做
ctx.user = user;
next();
});
},
function (ctx) {
console.log(ctx.user);
// 在这个中间件中再对用户信息作一些处理
// => { id: 17, name: "Alex" }
}
);
复制代码
咱们能够在应用中定义多个路由,而后把这些路由组合起来用,这样便于咱们管理多个路由,也简化了路由的写法。
var forums = new Router();
var posts = new Router();
posts.get('/', function (ctx, next) {...});
posts.get('/:pid', function (ctx, next) {...});
forums.use('/forums/:fid/posts', posts.routes(), posts.allowedMethods());
// 能够匹配到的路由为 "/forums/123/posts" 或者 "/forums/123/posts/123"
app.use(forums.routes());
复制代码
经过 prefix
这个参数,咱们能够为一组路由添加统一的前缀,和嵌套路由相似,也方便咱们管理路由和简化路由的写法。不一样的是,前缀是一个固定的字符串,不能添加动态参数。
var router = new Router({
prefix: '/users'
});
router.get('/', ...); // 匹配路由 "/users"
router.get('/:id', ...); // 匹配路由 "/users/:id"
复制代码
koa-router
也支持参数,参数会被添加到 ctx.params
中。参数能够是一个正则表达式,这个功能的实现是经过 path-to-regexp
来实现的。原理是把 URL
字符串转化成正则对象,而后再进行正则匹配,以前的例子中的 *
通配符就是一种正则表达式。
router.get('/:category/:title', function (ctx, next) {
console.log(ctx.params);
// => { category: 'programming', title: 'how-to-node' }
});
复制代码
经过上面的例子能够看出,咱们能够经过 ctx.params
去访问路由中的参数,使得咱们可以对参数作一些处理后再执行后续的代码。
使用了 koa-router
以后,代码简洁了不少。下一节中,咱们将学习下如何响应浏览器的各类请求。
下一篇:POST/GET请求——常见请求方式处理
上一篇:iKcamp新课程推出啦~~~~~iKcamp团队制做|基于Koa2搭建Node.js实战(含视频)☞ 中间件用法
2019年,iKcamp原创新书《Koa与Node.js开发实战》已在京东、天猫、亚马逊、当当开售啦!