Koa知识点与原理

606 阅读1分钟

知识点

koa

  • 概述:Koa 是一个新的 web 框架, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更 健壮的基石。
  • 特点:
    • 轻量,无捆绑
    • 中间件架构
    • 优雅的API设计
    • 增强的错误处理
  • 安装: npm i koa -S
  • 中间件机制、请求、响应处理

来个小例子

server.js

const Koa = require('koa')
const app = new Koa()
app.use((ctx, next) => {
  ctx.body = [
    {
    	name: 'icon'
    }
  ]
  next()
})

app.use((ctx, next) => {
  if (ctx.url === '/html') {
    ctx.type = 'text/html;charset=utf-8'
    ctx.body = `<b>我的名字是:${ctx.body[0].name}</b>`
  }
})

app.listen(3000)

执行命令:node server.js,在浏览器输入 http://localhost:3000/html 可以看到

1626315661(1).jpg

常见的中间件操作

  1. 静态服务
app.use(require('koa-static')(__dirname + '/static'))

当然也可以配置多个静态资源中间件

const static = require('koa-static');

app.use(static(__dirname + '/static'));
app.use(static(__dirname + '/public'));
  1. 路由
const router = require('koa-router')()
router.get('/string', async (ctx, next) => {
	ctx.body = 'koa2 string'
});

router.get('/json', async (ctx, next) => {
  ctx.body = {
  	title: 'koa2 json'
  }
});

app.use(router.routes());
  1. 日志
app.use(async (ctx,next) => {
  const start = new Date().getTime()
  console.log(`start: ${ctx.url}`);
  await next();
  const end = new Date().getTime()
  console.log(`请求${ctx.url}, 耗时${parseInt(end-start)}ms`)
})

koa 原理

  • 一个基于nodejs的入门级http服务,类似下面代码
const http = require('http')
const server = http.createServer((req, res)=>{
    res.writeHead(200)
    res.end('hi icon')
})

server.listen(3000,()=>{
    console.log('监听端口3000')
})
  • koa的目标是用更简单化、流程化、模块化的方式实现回调部分 myKoa.js
const http = require("http");

class MYKOA {
  listen(...args) {
    const server = http.createServer((req, res) => {
      this.callback(req, res);
    });
    server.listen(...args);
  }
  use(callback) {
    this.callback = callback;
  }
}
module.exports = MYKOA;

app.js

const MYKOA = require("./myKoa");
const myKoa = new MYKOA();

myKoa.use((req, res) => {
  res.writeHead(200);
  res.end("hi icon");
});

myKoa.listen(3000, () => {
  console.log("监听端口3000");
});

context

  • koa为了能够简化API,引入上下文context概念,将原始请求对象req和响应对象res封装并挂载到context 上,并且在context上设置getter和setter,从而简化操作。

app.js

app.use(ctx=>{
  ctx.body = 'hehe'
})
// request.js
module.exports = {
  get url() {
    return this.req.url;
  }
  get method(){
    return this.req.method.toLowerCase()
  }
};

// response.js
module.exports = {
  get body() {
    return this._body;
  },
  set body(val) {
    this._body = val;
  }
};

// context.js
module.exports = {
  get url() {
    return this.request.url;
  },
  get body() {
    return this.response.body;
  },
  set body(val) {
    this.response.body = val;
  },
  get method() {
    return this.request.method
  }
};

// myKoa.js
// 导入这三个类
const context = require("./context");
const request = require("./request");
const response = require("./response");

class MYKOA {
  listen(...args) {
    const server = http.createServer((req, res) => {
      // 创建上下文
      let ctx = this.createContext(req, res);
      
      this.callback(ctx)
      // 响应
      res.end(ctx.body);
    });
    // ...
  }
  
  // 构建上下文, 把res和req都挂载到ctx之上,并且在ctx.req和ctx.request.req同时保存
  createContext(req, res) {
    const ctx = Object.create(context);
    ctx.request = Object.create(request);
    ctx.response = Object.create(response);
    ctx.req = ctx.request.req = req;
    ctx.res = ctx.response.res = res;
    return ctx;
  }
}