疑问
在hello-koa工程中,我们处理http请求一律返回相同的HTML,这样虽然非常简单,但是用浏览器一测,随便输入任何URL都会返回相同的网页。
正常情况下,我们应该对不同的URL调用不同的处理函数,这样才能返回不同的结果。例如像这样写:
app.use(async (ctx, next) => { if (ctx.request.path === '/') { ctx.response.body = 'index page'; } else { await next(); } }); app.use(async (ctx, next) => { if (ctx.request.path === '/test') { ctx.response.body = 'TEST page'; } else { await next(); } }); app.use(async (ctx, next) => { if (ctx.request.path === '/error') { ctx.response.body = 'ERROR page'; } else { await next(); } });
这么写是可以运行的,但是好像有点蠢。
应该有一个能集中处理URL的middleware,它根据不同的URL调用不同的处理函数,这样,我们才能专心为每个URL编写处理函数。
koa-router
为了处理URL,我们需要引入koa-router这个middleware,让它负责处理URL映射。
我们把上一节的hello-koa工程复制一份,重命名为url-koa。
先在package.json中添加依赖项:
"koa-router": "7.0.0" 1.
然后用npm install安装。
接下来,我们修改app.js,使用koa-router来处理URL:
const Koa = require('koa'); // 注意require('koa-router')返回的是函数: const router = require('koa-router')(); const app = new Koa(); // log request URL: app.use(async (ctx, next) => { console.log(`Process ${ctx.request.method} ${ctx.request.url}...`); await next(); }); // add url-route: router.get('/hello/:name', async (ctx, next) => { var name = ctx.params.name; ctx.response.body = `<h1>Hello, ${name}!</h1>`; }); router.get('/', async (ctx, next) => { ctx.response.body = '<h1>Index</h1>'; }); // add router middleware: app.use(router.routes()); app.listen(3000); console.log('app started at port 3000...');
注意导入koa-router的语句最后的()是函数调用:
const router = require('koa-router')(); 1.
相当于:
const fn_router = require('koa-router'); const router = fn_router();
然后,我们使用router.get('/path', async fn)来注册一个GET请求。可以在请求路径中使用带变量的/hello/:name,变量可以通过ctx.params.name访问。
再运行app.js,我们就可以测试不同的URL:
输入首页:http://localhost:3000/