聊聊 koa 中间件

栏目: Node.js · 发布时间: 6年前

内容简介:koa是基于Node.js平台的下一代web开发框架,它体积小,扩展性强,给人一种干净利落的编程方式,且由express原班人马打造,国内很多互联网公司都在使用,因此有必要学习总结下。简捷的5行代码,帮我们开启了3000端口的服务学习Koa重点在于理解中间件实现原理,对后续引用第三方库中间件时候有更好了解。我们单独讲讲

koa是基于Node.js平台的下一代web开发框架,它体积小,扩展性强,给人一种干净利落的编程方式,且由express原班人马打造,国内很多互联网公司都在使用,因此有必要学习总结下。

初出茅庐,来个hello word

  • 按照惯例,先来个demo 输出hello world
let Koa = require('koa'); //引入koa
let app = new Koa();    //声明一个实例app
app.use(async (ctx,next)=>{   //  对于任何请求,app将调用该异步函数处理请求:
    ctx.body = "hello"
});
app.listen("3000");  //监听端口
复制代码
  • 其中参数ctx是由koa传入的封装了request和response的变量,我们可以通过它访问request和response。
  • next是koa传入的将要处理的下一个异步函数。
  • 由async标记的函数称为异步函数,在异步函数中,可以用await调用另一个异步函数,这个异步函数必须返回一个promise, 上篇文章写过promise用法和实现原理,不了解可以先去看看 。这两个关键字将在ES7中引入。
聊聊 koa 中间件

简捷的5行代码,帮我们开启了3000端口的服务

深入理解Koa中间件之洋葱模型

学习Koa重点在于理解中间件实现原理,对后续引用第三方库中间件时候有更好了解。我们单独讲讲

  • 先来段测试代码
let Koa = require('koa');
let app = new Koa();
app.use(async (ctx,next)=>{
    console.log(1);
   await next();
    console.log(2);
});
app.use(async (ctx,next)=>{
    console.log(3);
   await next();
    console.log(4);
});
app.listen("3000");
复制代码

你可能对运行的结果会说 1234,其实不然,我们先来看下输出结果

聊聊 koa 中间件
聊聊 koa 中间件

一脸懵逼1342,这是什么顺序,这就是我们要说的洋葱模型

  • 中间件的执行很像一个洋葱,但并不是一层一层的执行,而是以next为分界,先执行本层中next以前的部分,当下一层中间件执行完后,再执行本层next以后的部分。
  • 一个洋葱结构,从上往下一层一层进来,再从下往上一层一层回去,是不是有点感觉了。
聊聊 koa 中间件

1、koa-router中间件

koa-router基础写法

  • 为了讲的详细全面,把路由分为及部分来讲解,先来看最基本的路由怎么写
let Koa = require('koa');
let app = new Koa();
let Router = require('koa-router');
let router = new Router();
router.get('/',async (ctx,next)=>{
    ctx.body = 'hello people';
    await next()
});
router.get('/list',async (ctx,next)=>{
    ctx.body = 'list';
});
app.use(router.routes()); // 挂载
app.use(router.allowedMethods());//当请求数据的方法与设置的方法不一致,会报错。比如默认get请求获取,用post发请求会报错
app.listen(3000);
复制代码

koa-router中嵌套路由写法

假如我们想为单个页面设置层级,/home是我们首页,再次基础上有/home/list 首页列表页 /home/todo 首页todo页。这时我们就需要用到嵌套路由,看看怎么用

const Koa = require('koa');
const app = new Koa();
const Router = require('koa-router');
//home的路由
let home = new Router();
home.get('/list',async(ctx)=>{
    ctx.body="Home list";
}).get('/todo',async(ctx)=>{
    ctx.body ='Home ToDo';
});
//page的路由
let page = new Router();
page.get('/list',async(ctx)=>{
    ctx.body="Page list";
}).get('/todo',async(ctx)=>{
    ctx.body ='Page todo';
});
//装载所有子路由
let router = new Router();
router.use('/home',home.routes(),home.allowedMethods());
router.use('/page',page.routes(),page.allowedMethods());
//加载路由中间件
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000);

复制代码

这样一来就实现嵌套路由的写法

聊聊 koa 中间件

koa-router参数的传递

  • 1、通过/arcicle/id/name传参
let Koa = require('koa');
let app = new Koa();
let Router = require('koa-router');
let router = new Router();
//实现  /arcicle/id/name形式的传参
router.get('/acticle/:id/:name',(ctx,next)=>{
    ctx.body = ctx.params.id +"-"+ ctx.params.name;
});
app.use(router.routes());
app.listen(3000);
复制代码

测试下,学过vue应该比较熟悉

聊聊 koa 中间件
  • 2、通过/arcicle?id=1&name=cgp传参
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
router.get('/article', function (ctx, next) {
    ctx.body=ctx.query; //query方法实现json形式
});
app.use(router.routes())
app.listen(3000,()=>{
    console.log('starting at port 3000');
});
复制代码
聊聊 koa 中间件

2、koa-bodyparse()中间件

  • 用来解析请求体的中间件,比如获取post提交的表单数据,通过koa-bodyparse解析后就能获取到数据。看demo
let Koa = require('koa');
let bodyParser = require('koa-bod')
let app = new Koa();
app.use(bodyParser()); // 解析请求体的中间件
app.use(async (ctx, next) => {
    if (ctx.path === '/' && ctx.method === 'GET') {
        ctx.set('Content-Type', 'text/html;charset=utf8');
        ctx.body = `
        <form action="/" method="post">
            <input type="text" name="username" >
            <input type="text" name="password" >
            <input type="submit" >
        </form>
        `
    }
});
app.use(async (ctx, next) => {
    if (ctx.method === 'POST' && ctx.path === '/') {
        // 获取表单提交过来的数据
        ctx.body = ctx.request.body;
    }
});
app.listen(3000);

复制代码

当post提交表单获得表单数据,测试下结果

聊聊 koa 中间件

3、koa-better-body中间件

  • 是用来上传文件的中间件
  • 由于老的中间件都是基于koa1版本的generate函数实现的,在koa2中我们需要用koa-convert,可以将他们转为基于Promise的中间件供Koa2使用

来个demo体验下,我们把本地的1.txt文件上传到upload文件夹中。 1.txt内容为123456789

let Koa = require('koa');
let app = new Koa();
let betterBody = require('koa-better-body'); // v1插件 
let convert = require('koa-convert'); // 将1.0的中间件 转化成2.0中间件
app.use(convert(betterBody({
    uploadDir: __dirname //指定上传的目录 __dirname当前文件夹绝对路径
})))
app.use(async (ctx, next) => {
    if (ctx.path === '/' && ctx.method === 'GET') {
        ctx.set('Content-Type', 'text/html;charset=utf8');
        ctx.body = `
        <form action="/" method="post" enctype="multipart/form-data">
            <input type="text" name="username" autoComplete="off">
            <input type="text" name="password" autoComplete="off">
            <input type="file" name="avatar">
            <input type="submit" >
        </form>
        `
    } else {
        return next();
    }
});
app.use(async (ctx, next) => {
    if (ctx.method === 'POST' && ctx.path === '/') {
        // 获取表单提交过来的数据
        ctx.body = ctx.request.fields;
    }
});
app.listen(1000);
复制代码

看下上传结果

聊聊 koa 中间件

内容也是正确的,我就不给大家展示拉

4、kao-views中间件

  • koa-views对需要进行视图模板渲染的应用是个不可缺少的中间件,支持ejs, nunjucks等众多模板引擎。

我们以ejs为例子

let Koa = require('koa');
let app = new Koa();
let views = require('koa-views');
app.use(views(__dirname,{
    extension:'ejs' //指定用ejs模板
}));
app.use(async (ctx,next)=>{
    // 渲染index.ejs
    await ctx.render('index',{name:'cgp',age:9,arr:[1,2,3]});
});
app.listen(3000);
复制代码
  • 我们来看下index.ejs模板是怎么写的。ejs语法戳这里
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <h1><%=name%></h1>
    <h1><%=age%></h1>
    <ul>
        <%arr.forEach(item=>{%>
             <li><%=item%></li>
        <%})%>
    </ul>
</body>
</html>

复制代码
  • 我们这里写的模板很简单,就是输出下name、age,然后循环下数组
聊聊 koa 中间件

5、koa-static

let Koa = require('koa');
let server = require('koa-static');
let app = new Koa();
app.use(server(__dirname +'/public'));
app.listen(3000);
复制代码
  • 用法很简单,有兴趣可以看下我写的静态服务器

6、koa自带cookie用法

比如我们要存储用户名,保留用户登录状态时,会用到cookie。

共两个方法

  • ctx.cookies.get()
  • ctx.cookies.set()

先来个demo测试,当输入/write写入cookie,当输入/read读到cookie

let Koa = require('koa');
let Router = require('koa-router');
let app = new Koa();
let router = new Router();
router.get('/read', (ctx, next) => {
    //有name读name
    let name = ctx.cookies.get("name") || '没有name';
    let age = ctx.cookies.get("age") || '没有age';
    ctx.body = `${name}-${age}`;
});
router.get('/write', (ctx, next) => {
    ctx.cookies.set('name', 'cgp',{
        domain:'127.0.0.1', //写入cookie所在的域名
        path:'/write',    // 写入cookie最大的路径
        maxAge:10*1000,    //Cookie最大有效时长
        httpOnly:false,  // 是否只用于http请求中获取
        overwrite:false  // 是否允许重写
    });
    ctx.cookies.set('age', '9');
    ctx.body = 'write Ok';
});
app.use(router.routes());
app.listen(4000);
复制代码

Cookie选项

  • domain:写入cookie所在的域名
  • path:写入cookie所在的路径
  • maxAge:Cookie最大有效时长
  • expires:cookie失效时间
  • httpOnly:是否只用http请求中获得
  • overwirte:是否允许重写

看下运行结果吧

聊聊 koa 中间件

以上所述就是小编给大家介绍的《聊聊 koa 中间件》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Code

Code

Charles Petzold / Microsoft Press / 2000-10-21 / USD 29.99

Paperback Edition What do flashlights, the British invasion, black cats, and seesaws have to do with computers? In CODE, they show us the ingenious ways we manipulate language and invent new means of ......一起来看看 《Code》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

html转js在线工具
html转js在线工具

html转js在线工具