koa2 从入门到进阶(二)-路由

    |     2020年2月1日   |   koa2, web前端技术   |     0 条评论   |    1092

上一篇已经能在本地启动一个最简单的 Koa 应用。这一篇把重点放到 路由:怎么按 URL 返回不同内容、怎么接 GET 传值,以及怎么写 动态路由。

和 Express 不同,Koa 内核不自带路由,需要单独安装 koa-router。GET 参数既可以从 ctx.query 拿对象,也可以从路径参数 ctx.params 拿。

一、Koa 路由是什么

路由由一个 URI(路径)和一种 HTTP 方法(GET、POST 等)组成,决定应用如何响应客户端对某个节点的访问。通俗讲:根据不同 URL,加载不同页面、实现不同功能。

Express 里引入框架就能配路由;Koa 必须先装路由模块:

npm install koa-router --save

二、配置基础路由

接着上一节的项目目录改 app.js。用 router.get() 分别处理 / 和 /news,再用 app.use(router.routes()) 启动路由。

//引入 koa模块
var Koa = require('koa');
var Router = require('koa-router');

//实例化
var app = new Koa();
var router = new Router();

//配置路由
router.get('/', async (ctx) => {
    // ctx  上下文 context ,包含了request 和response等信息
    // 返回数据    相当于:原生里面的res.writeHead()  res.end()
    ctx.body = '首页';
});
router.get('/news', async (ctx) => {
    ctx.body = "新闻页面";
});

//启动路由
app.use(router.routes());
app.use(router.allowedMethods());
/**
 router.allowedMethods()作用: 这是官方文档的推荐用法,我们可以
 看到 router.allowedMethods()用在了路由匹配 router.routes()之后,所以在当所有
 路由中间件最后调用.此时根据 ctx.status 设置 response 响应头
 可以配置也可以不配置,建议配置,
 */

app.listen(3000);

ctx 是上下文,里面有 request 和 response。给 ctx.body 赋值,相当于原生里的 res.writeHead() + res.end()。本地启动后访问 / 是首页,访问 /news 会看到「新闻页面」。

router.allowedMethods() 官方建议写在 router.routes() 之后:所有路由中间件跑完,再根据 ctx.status 补响应头。可以不配,建议配上。

三、GET 传值:query 与 querystring

实际地址经常长这样:http://localhost:3000/news?id=1&title=aaa。问号后面的值,Koa2 通过 request 接收,方法有两种:query 返回格式化好的对象,querystring 返回请求字符串。推荐用得最多的 ctx.query。

//引入 koa模块
var Koa = require('koa');
var Router = require('koa-router');

//实例化
var app = new Koa();
var router = new Router();

//配置路由
router.get('/', async (ctx) => {
// ctx 上下文 context ,包含了request 和response等信息
// 返回数据 相当于:原生里面的res.writeHead() res.end()
ctx.body = '首页';
});
router.get('/news', async (ctx) => {
/**
在 koa2 中 GET 传值通过 request 接收,但是接收的方法有两种:query 和 querystring。
query:返回的是格式化好的参数对象。
querystring:返回的是请求字符串。
*/

//从ctx中读取get传值
console.log(ctx.url); // /news?id=1&title=aaa
console.log(ctx.query); // { id: '1', title: 'aaa' } 获取的是对象 用的最多的方式 ******推荐
console.log(ctx.querystring); // id=1&title=aaa 获取的是一个字符串

//ctx里面的request里面获取get传值
console.log(ctx.request.url); // /news?id=1&title=aaa
console.log(ctx.request.query); // { id: '1', title: 'aaa' } 对象
console.log(ctx.request.querystring); // id=1&title=aaa
ctx.body = "新闻页面";
});

//启动路由
app.use(router.routes());
app.use(router.allowedMethods());
/**
router.allowedMethods()作用: 这是官方文档的推荐用法,我们可以
看到 router.allowedMethods()用在了路由匹配 router.routes()之后,所以在当所有
路由中间件最后调用.此时根据 ctx.status 设置 response 响应头
可以配置也可以不配置,建议配置,
*/

app.listen(3000);

ctx 上能直接读 url / query / querystring,ctx.request 里同样有这三项,输出一致。浏览器打开上面的地址后,编辑器控制台就能打出对象和字符串。

四、动态路由与 ctx.params

还有一种地址不是查询串,而是路径本身带参数,例如 http://localhost:3000/news/123。如果写成死路径 /news/123,后面换成别的数字就得再写一条路由,显然不可取。这时用动态路由 /news/:id,再用 ctx.params 取值。

//引入 koa模块
var Koa = require('koa');
var Router = require('koa-router');

//实例化
var app = new Koa();
var router = new Router();

//配置路由
router.get('/', async (ctx) => {
    // ctx  上下文 context ,包含了request 和response等信息
    // 返回数据    相当于:原生里面的res.writeHead()  res.end()
    ctx.body = '首页';
});
router.get('/news/:id', async (ctx) => {
    /**
     获取动态路由传参
     */

    //从ctx中读取get传值
    console.log(ctx.url);   // /news/123
    console.log(ctx.params);  // { id: '123' }
    ctx.body = "新闻页面";
});

//启动路由
app.use(router.routes());
app.use(router.allowedMethods());
/**
 router.allowedMethods()作用: 这是官方文档的推荐用法,我们可以
 看到 router.allowedMethods()用在了路由匹配 router.routes()之后,所以在当所有
 路由中间件最后调用.此时根据 ctx.status 设置 response 响应头
 可以配置也可以不配置,建议配置,
 */

app.listen(3000);

把原来的 router.get('/news') 改成 router.get('/news/:id') 后,访问 /news/123,控制台会打出 { id: '123' }。

场景 示例 URL 怎么取 得到什么
固定路径 /news router.get(‘/news’) 匹配整段路径
查询串对象 /news?id=1&title=aaa ctx.query(推荐) { id: ‘1’, title: ‘aaa’ }
查询串原文 同上 ctx.querystring id=1&title=aaa
动态路径 /news/123 ctx.params { id: ‘123’ }

引自:https://www.cnblogs.com/weijiutao/p/10688892.html

一句话总结:Koa 路由靠 koa-router;问号参数用 ctx.query,路径参数用 /news/:id 加 ctx.params。

转载请注明来源:koa2 从入门到进阶(二)-路由
本文链接地址:https://ai.zhousir.top/?p=2376
回复 取消