路由koa-router——MVC 中重要的环节:Url 处理器

?? iKcamp 制作团队

原创作者:大哼、阿干、三三、小虎、胖子、小哈、DDU、可木、晃晃
文案校对:李益、大力萌、Au、DDU、小溪里、小哈
风采主播:可木、阿干、Au、DDU、小哈
视频剪辑:小溪里
主站运营:给力xi、xty
教程主编:张利涛


视频地址:www.cctalk.com/v/151149238…

文章

路由 koa-router

上一节我们学习了中间件的基本概念,本节主要带大家学习下 koa-router 路由中间件的使用方法。

路由是用于描述 URL 与处理函数之间的对应关系的。比如用户访问 http://localhost:3000/,那么浏览器就会显示 index 页面的内容,如果用户访问的是 http://localhost:3000/home,那么浏览器应该显示 home 页面的内容。

要实现上述功能,如果不借助 koa-router 或者其他路由中间件,我们自己去处理路由,那么写法可能如下所示:

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/homehttp://localhost:3000/404 就能看到相应的页面了。

上述 app.js 的代码中,由 async 标记的函数称为『异步函数』,在异步函数中,可以用 await 调用另一个异步函数,asyncawait 这两个关键字将在 ES7 中引入。参数 ctx 是由 koa 传入的,我们可以通过它来访问 requestresponsenextkoa 传入的将要处理的下一个异步函数。

注意: 由于 nodev7.6.0 中才支持 asyncawait,所以在运行 app.js 之前请确保 node 版本正确,或者使用一些第三方的 async 库来支持。

这样的写法能够处理简单的应用,但是,一旦要处理的 URL 多起来的话就会显得特别笨重。所以我们可以借助 koa-router 来更简单的实现这一功能。 下面来介绍一下如何正确的使用 koa-router

安装 koa-router

通过 npm 命令直接安装:

npm i koa-router -S
复制代码

-S 或者 --save 是为了安装完成之后能够在 package.jsondependencies 中保留 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 协议方法中,GETPOSTPUTDELETE 分别对应 ,这里 router 的方法也一一对应。通常我们使用 GET 来查询和获取数据,使用 POST 来更新资源。PUTDELETE 使用比较少,但是如果你们团队采用 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
});
复制代码

上面例子中两个方法最主要的区别就是 ajaxmethod 的值,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"
复制代码

URL 参数

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实战(含视频)☞ 中间件用法

推荐: 翻译项目Master的自述:

1. 干货|人人都是翻译项目的Master

2. iKcamp出品微信小程序教学共5章16小节汇总(含视频)


2019年,iKcamp原创新书《Koa与Node.js开发实战》已在京东、天猫、亚马逊、当当开售啦!

iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 路由koa-router相关推荐

  1. iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 处理静态资源

    视频地址:www.cctalk.com/v/151149238- 处理静态资源 无非花开花落,静静. 指定静态资源目录 这里我们使用第三方中间件: koa-static 安装并使用 安装 koa-st ...

  2. iKcamp团队制作|基于Koa2搭建Node.js实战(含视频)☞ 中间件用法

    中间件用法--讲解 Koa2 中间件的用法及如何开发中间件 ?? iKcamp 制作团队 原创作者:大哼.阿干.三三.小虎.胖子.小哈.DDU.可木.晃晃 文案校对:李益.大力萌.Au.DDU.小溪里 ...

  3. iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 记录日志

    为什么80%的码农都做不了架构师?>>>    沪江CCtalk视频地址:https://www.cctalk.com/v/15114923883523 log 日志中间件 最困难的 ...

  4. iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 规范与部署

    为什么80%的码农都做不了架构师?>>>    沪江CCtalk视频地址:https://www.cctalk.com/v/15114923889450 规范与部署 懒人推动社会进步 ...

  5. python爬取cctalk视频_iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 处理静态资源

    处理静态资源 无非花开花落,静静. 指定静态资源目录 这里我们使用第三方中间件: koa-static 安装并使用 安装 koa-static: npm i koa-static -S 修改 app. ...

  6. 用node.js 搭建的博客程序心得(node.js实战读书笔记1)

    学习node已经有一段时间了,之前把了不起的node.js看完了,基本算了解了一些node的基本的用法还有一些概念了,然后就开始看第二本node.js实战,第一章就是搭建一个博客程序.但是不得不吐槽一 ...

  7. 分享Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站

    这是个什么的项目? 使用 Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站. 博客线上地址:www.boblog.com Github地址:https: ...

  8. 详细记录基于vue+nodejs+mongodb构建的商城学习(四)基于项目的node.js开发后端的学习与梳理总结...

    前置: 本系列文章是一个本人边学习边梳理的学习笔记,俗话说好脑袋不如烂笔头,再好的记忆力时间长了也会有细节忘记,本项目选择的前端框架是vue,后端开发使用是node.js,数据库使用的是mongodb ...

  9. 妙味课堂ajax教程,前后端高级实战 | Node.js 实战开发:博客系统【妙味课堂】

    第一部分:Node.js基础视频内容 1-初识NodeJs 2-webstorm的使用 3-Node和JS的异同 4-模块的使用 5-模块加载机制 6-模块-module和exports 7-glob ...

最新文章

  1. angularjs -- 路由监听
  2. 高性能服务器架构(二):缓存清理策略
  3. Windows批处理(cmd/bat)常用命令
  4. Effective C#:避免使用ICloneable接口
  5. 您应该考虑将应用程序升级到Spring 4的5个理由
  6. 7 QM配置-质量计划配置-定义检验方法的编号范围
  7. koa源码分析-generator和yield分析
  8. 【华为云技术分享】数据赋能,如何精细化保障企业大数据安全
  9. 使用命令将logcat中的内容输出到文本文件中
  10. 程序员面试金典——3.6双栈排序
  11. 基于深度学习的2D和3D仿射变换配准
  12. 《推荐系统实践》算法纯享(附代码链接)(四)—— UGC推荐篇
  13. php被挂马,近日报网站被挂马的解决方法
  14. OSM数据下载及两种格式转换方法(shp等格式)
  15. 《茅屋为秋风所破歌》古诗鉴赏
  16. iconv 静态库的编译
  17. 数据可视化|用堆叠条形图进行对比分析
  18. so-vits-svc4.0 中文详细安装、训练、推理使用教程
  19. xp计算机能装win系统吗,自己用的电脑要装系统,XP, Win7, Win10到底选哪个?解救小白篇...
  20. 采用STM32外部中断模式控制LED灯亮灭

热门文章

  1. PL/SQL语言基础
  2. 《代码阅读方法与实践之读书笔记之一》
  3. 一天一个命令--ifconfig
  4. 关于Block的copy和循环引用的问题
  5. Silverlight测试——利用Ranorex实现数据驱动测试
  6. Win2003用NAT实现ADSL共享与×××服务器
  7. Linux初级运维(七)——bash脚本编程(常见测试)
  8. python:文件操作
  9. HTML5 如何实现拖放'N'拖放
  10. 设置更改root密码(远程,本地)、连接mysql、mysql常用命令