了解使用node项目中的Koa

255 阅读2分钟

简介

koa是由Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的Web框架。使用 koa编写web应用,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率。koa不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写Web应用变得得心应手。

创建一个koa项目

  1. 先起一个空项目安装依赖
    npm init --yes
    npm install koa
  1. 引入依赖
    //引入Koa
    const koa = require('koa');
    const app = new koa();
    app.use(async (ctx, next) => {
      console.log(`${ctx.request.method} ${ctx.request.url}`); // 打印URL
      await next(); // 调用下一个middleware
    });

    app.use(async (ctx, next) => {
      const start = new Date().getTime(); // 当前时间
      await next(); // 调用下一个middleware
      const ms = new Date().getTime() - start; // 耗费时间
      console.log(`Time: ${ms}ms`); // 打印耗费时间
    });

    app.use(async (ctx, next) => {
      await next();
      ctx.response.type = 'text/html';
      ctx.response.body = '<h1>Hello, koa2!</h1>';
    });
    //监听端口
    app.listen(3000);

每收到一个http请求,koa就会调用通过app.use()注册的async函数,并传入ctxnext参数,middleware的顺序很重要,也就是调用app.use()的顺序决定了middleware的顺序。

这里没对url进行处理无论什么路径都是返回相同的结果,所以我们需要一个集中管理http请求的中间件。

使用koa-router来管理http请求

我们讲上面hello koa项目进行修改,安装并添加koa-router依赖,添加路由管理代码。

    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...');

我们router.get方法来处理get请求,访问localhost:3000/hello/xxx可以看到Hello,xxx页面,类似的post、put、delete、head请求也可以由router处理。

但是我们用post请求处理URL时,我们会遇到一个问题:post请求通常会发送一个表单,或者JSON,它作为request的body发送,但无论是Node.js提供的原始request对象,还是koa提供的request对象,都不提供解析request的body的功能,所以,我们又需要引入另一个middleware来解析原始request请求,然后,把解析后的参数,绑定到ctx.request.body中。

使用koa-bodyparser来处理request.body数据

我在项目中安装添加koa-bodyparser依赖来处理ctx.request.body数据,由于middleware的顺序很重要,这个koa-bodyparser必须在router之前被注册到app对象上。

const bodyParser = require('koa-bodyparser');

app.use(bodyParser());

router.post('/signin', async (ctx, next) => {
    var
        name = ctx.request.body.name || '',
        password = ctx.request.body.password || '';
    console.log(`signin with name: ${name}, password: ${password}`);
    if (name === 'koa' && password === '12345') {
        ctx.response.body = `<h1>Welcome, ${name}!</h1>`;
    } else {
        ctx.response.body = `<h1>Login failed!</h1>
        <p><a href="/">Try again</a></p>`;
    }
});