KOA学习笔记

LeslieLin 编程技术
阅读量 0 评论量 0

前言

由于业务需求,故大致学习一下KOA框架。

环境搭建

mkdir KOA
cd KOA
npm init -y # 初始化package.json文件
npm install --save koa # 安装KOA

HelloKoa

const Koa = require('koa')
const app = new Koa()

app.use(async (ctx) => {
  ctx.body = 'hello koa'
})

app.listen(3000)
console.log('listening at port 3000')

GET请求的接收

原生方法

const Koa = require('koa');
const app = new Koa();
app.use(async (ctx) => {
  let url = ctx.url;

  // 从request中获取GET请求
  let request = ctx.request;
  let req_query = request.query;// query:返回的是格式化好的参数对象
  let req_querystring = request.querystring;// 返回的是请求字符串

  // 从上下文中直接获取
  let ctx_query = ctx.query;
  let ctx_querystring = ctx.querystring;

  ctx.body = {
    url,
    req_query,
    req_querystring,
    ctx_query,
    ctx_querystring
  }

});

app.listen(3000, () => {
  console.log('listening at port 3000');
});

POST接收请求

Caps 1

获取POST请求步骤:

  1. 解析上下文ctx中的原生nodex.js对象req。
  2. 将POST表单数据解析成query string-字符串.(例如:user=jspang&age=18)
  3. 将字符串转换成JSON格式。

ctx.request和ctx.req的区别

  • ctx.request:是Koa2中context经过封装的请求对象,它用起来更直观和简单。
  • ctx.req:是context提供的node.js原生HTTP请求对象。这个虽然不那么直观,但是可以得到更多的内容,适合我们深度编程。

ctx.method 得到请求类型,用法如下

const Koa = require('koa');
const app = new Koa();
app.use(async(ctx)=>{
    // 当请求时GET请求时,显示表单让用户填写
    if(ctx.url==='/' && ctx.method === 'GET'){
        let html =`
            <h1>Koa request post demo</h1>
            <form method="POST"  action="/">
                <p>userName</p>
                <input name="userName" /> <br/>
                <p>age</p>
                <input name="age" /> <br/>
            </form>
        `;
        ctx.body =html;
    // 当请求时POST请求时
    }else if(ctx.url==='/' && ctx.method === 'POST'){
        ctx.body='接收到请求';
    }else{
        // 其它请求显示404页面
        ctx.body='<h1>404!</h1>';
    }
})

app.listen(3000,()=>{
    console.log('listening at port 3000');
})

Caps 2

声明一个方法,使用Promise对象解析。

function parsePostData(ctx) {
  return new Promise((resolve, reject) => {
    try {
      let postdata = "";
      ctx.req.on('data', (data) => {
        postdata += data
      })
      ctx.req.addListener("end", function () {

        resolve(postdata);
      })
    } catch (error) {
      reject(error);
    }
  });
}

完整代码

const Koa = require('koa')
const app = new Koa()

function parsePostData(ctx) {
  return new Promise((resolve, reject) => {
    try {
      let postdata = "";
      ctx.req.on('data', (data) => {
        postdata += data
      })
      ctx.req.addListener("end", function () {

        resolve(postdata);
      })
    } catch (error) {
      reject(error);
    }
  });
}

function parseQueryStr(queryStr) {
  if (queryStr == '' || queryStr == null) {
    return {}
  }
  let queryData = {};
  let queryStrList = queryStr.split('&');
  console.log(queryStrList);
  for (let [index, queryStr] of queryStrList.entries()) {
    let itemList = queryStr.split('=');
    // console.log(itemList);
    queryData[itemList[0]] = decodeURIComponent(itemList[1]);
  }
  return queryData
}

app.use(
  async (ctx) => {
    let url = ctx.url;
    let request = ctx.request;
    let req_query = request.query;
    let req_querystring = request.querystring;

    //从上下文中直接获取
    let ctx_query = ctx.query;
    let ctx_querystring = ctx.querystring;

    // POST
    let postData = await parsePostData(ctx)
    postData = parseQueryStr(postData)

    ctx.body = {
      url,
      req_query,
      req_querystring,
      ctx_query,
      ctx_querystring,
      postData
    }
  }
)

app.listen(3000, () => {
  console.log('listening at port 3000')
})

koa-bodyparser中间件

上面的写法是原生实现的,koa已经给我们造好了一个轮子,也就是koa-bodyparser。对于POST请求的处理,koa-bodyparser中间件可以把koa上下文的formData数据解析到ctx.request.body中。

安装

npm install --save koa-bodyparser@3

完整代码

const Koa = require('koa');
const app = new Koa();
const bodyParser = require('koa-bodyparser');

app.use(bodyParser());

app.use(async (ctx) => {
  if (ctx.url === '/' && ctx.method === 'GET') {
    //显示表单页面
    let html = `
            <h1>JSPang Koa2 request POST</h1>
            <form method="POST" action="/">
                <p>userName</p>
                <input name="userName" /><br/>
                <p>age</p>
                <input name="age" /><br/>
            </form>
        `;
    ctx.body = html;
  } else if (ctx.url === '/' && ctx.method === 'POST') {
    let postData = ctx.request.body;
    ctx.body = postData;
  } else {
    ctx.body = '<h1>404!</h1>';
  }

});


app.listen(3000, () => {
  console.log('listening at port 3000');
});

Koa原生路由实现

const Koa = require('koa');
const fs = require('fs');// nodejs的fs模块
const app = new Koa();

function render(page) {
  return new Promise((resolve, reject) => {
    let pageUrl = `./page/${page}`;
    fs.readFile(pageUrl, "binary", (err, data) => {
      if (err) {
        reject(err)
      } else {
        resolve(data);
      }
    })
  })
}

async function route(url) {
  let page = '404.html';
  switch (url) {
    case '/':
      page = 'index.html';
      break;
    case '/index':
      page = 'index.html';
      break;
    case '/404':
      page = '404.html';
      break;
    default:
      break;
  }
  let html = await render(page);
  return html;
}

app.use(async (ctx) => {
  let url = ctx.request.url;
  let html = await route(url);
  ctx.body = html;
})
app.listen(3000);
console.log('listening at 3000');

Koa-router中间件

安装

npm install --save koa-router
const Koa = require('koa');
const Router = require('koa-router');

const app = new Koa();
const router = new Router();

// 多页面的添加只要继续在下面填写get或者Post即可
router.get('/', function (ctx, next) {
  ctx.body = "Hello Koa";
})
  .get('/todo', (ctx, next) => {
    ctx.body = "Todo page"
  });

app
  .use(router.routes())
  .use(router.allowedMethods());
app.listen(3000, () => {
  console.log('listening at port 3000');
});

Koa中使用cookies

了解基本的参数

  • ctx.cookies.get(name,[optins]):读取上下文请求中的cookie。
  • ctx.cookies.set(name,value,[options]):在上下文中写入cookie。
const Koa = require('koa');
const app = new Koa();

app.use(async (ctx) => {
  if (ctx.url === '/index') {
    ctx.cookies.set(
      'MyName', 'Carlos'
    );
    ctx.body = 'cookie is ok';
  } else {
    ctx.body = 'hello world'
  }
});

app.listen(3000, () => {
  console.log('listening at port 3000');
})
  • domain:写入cookie所在的域名
  • path:写入cookie所在的路径
  • maxAge:Cookie最大有效时长
  • expires:cookie失效时间
  • httpOnly:是否只用http请求中获得
  • overwirte:是否允许重写
const Koa = require('koa');
const app = new Koa();

app.use(async (ctx) => {
  if (ctx.url === '/index') {
    ctx.cookies.set(
      'MyName', 'Carlos', {
        domain: '127.0.0.1', // 写cookie所在的域名
        path: '/index',       // 写cookie所在的路径
        maxAge: 1000 * 60 * 60 * 24,   // cookie有效时长
        expires: new Date('2020-3-12'), // cookie失效时间
        httpOnly: false,  // 是否只用于http请求中获取
        overwrite: false  // 是否允许重写
      }
    );
    ctx.body = 'cookie is ok';
  } else {
    ctx.body = 'hello world'
  }
});

app.listen(3000, () => {
  console.log('listening at port 3000');
})
const Koa = require('koa');
const app = new Koa();

app.use(async (ctx) => {
  if (ctx.url === '/index') {
    ctx.cookies.set(
      'MyName', 'Carlos', {
        domain: '127.0.0.1', // 写cookie所在的域名
        path: '/index',       // 写cookie所在的路径
        maxAge: 1000 * 60 * 60 * 24,   // cookie有效时长
        expires: new Date('2020-3-12'), // cookie失效时间
        httpOnly: false,  // 是否只用于http请求中获取
        overwrite: false  // 是否允许重写
      }
    );
    ctx.body = 'cookie is ok';
  } else {
    if (ctx.cookies.get('MyName')) {
      ctx.body = ctx.cookies.get('MyName');
    } else {
      ctx.body = 'Cookie is none';
    }

  }
});

app.listen(3000, () => {
  console.log('listening at port 3000');
})
喵~