koa 使用

(贴个官网,koa 内容真不多,非常的小巧轻量)

1. koa 是什么

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

基础样例:

const koa = require("koa");

const app = new koa(); // express 不用 new,是 const app = express();

app.use(async (ctx, next) => { // 为应用添加指定的中间件
    console.log(ctx.request.path); // 打印请求的 url 路径部分
    // ctx.response.body = "<b>Hello World</b>"; // 设置响应体 
    // ctx.response.body = "Hello World"; // 设置响应体
    ctx.response.body = {name: "bob"}; // 设置响应体
})

app.listen(3000); // 监听 3000 端口

2. ctx 参数

该 context 在每个 request 请求中被创建,在中间件中作为接收器来引用,或者通过 this 标识符来引用,其身上几个重要的属性:

  1. ctx.req:Node 的 request 对象
  2. ctx.res:Node 的 response 对象
  3. ctx.request:Koa 的 Request 对象
  4. ctx.response:Koa 的 Response 对象
  5. ctx.cookies.get(name, [options]):获得 cookie 中名为 name 的值,options 为可选参数
  6. ctx.cookies.set(name, value, [options]):设置 cookie 中名为 name 的值,options 为可选参数
  7. ctx.throw([status], [msg], [properties]):抛出包含 .status 属性的错误,默认为 500。该方法可以让 Koa 准确的响应处理状态,例 ctx.throw(400, ‘name required’, { user: user });

【注:app.context 是从中创建 ctx 的原型。 可以通过编辑 app.context 向 ctx 添加其他属性,当需要将 ctx 添加到整个应用程序中使用的属性或方法时,这将会非常有用。例,向 ctx 中添加对数据库的引用】

app.context.db = db();

app.use(async ctx => {
  console.log(ctx.db);
});

【注:许多 context 的访问器和方法为了便于访问和调用,简单的委托给他们的 ctx.request 和 ctx.response 所对应的等价方法, 比如说 ctx.type,ctx.length,ctx.body 代理了 response 对象中对应的方法,ctx.path,ctx.method,ctx.header 代理了 request 对象中对应的方法】

3. next 参数

当执行到 next 语句时,Koa 暂停了该中间件,继续执行下一个符合请求的中间件,执行完后,然后将控制权再逐级返回给上层中间件

下面的例子在页面中返回 “Hello World”,然而当请求开始时,请求先经过 x-response-time 和 logging 中间件,并记录中间件执行起始时间。 然后将控制权交给 reponse 中间件。当一个中间件调用next()函数时,函数挂起并控件传递给定义的下一个中间件。在没有更多的中间件执行下游之后,堆栈将退出,并且每个中间件被恢复以执行其上游行为

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

// x-response-time

app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
});

// logger

app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  console.log(`${ctx.method} ${ctx.url} - ${ms}`);
});

// response

app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3000);

4. request 对象

Koa Request 对象是对 node 的 request 进一步抽象和封装,提供了日常 HTTP 服务器开发中一些有用的功能,常用api有:

  1. request.header:获得或设置请求头对象(request.headers 等价)
  2. request.method:获得或设置请求方法
  3. request.length:以数字的形式返回 request 的内容长度(Content-Length),或者返回 undefined
  4. request.url:获得或设置请求 url 地址
  5. request.href:获取完整的请求URL, 包含 protocol, host 和 url
  6. request.path:获取请求路径名,或设置请求路径名并保留当前查询字符串
  7. request.querystring:获取查询参数字符串(url中?后面的部分,不包含?),或设置原始查询字符串
  8. request.search:获取查询参数字符串(包含?),或设置原始查询字符串
  9. request.type:获取请求 Content-Type,不包含像 “charset” 这样的参数
  10. request.is(types…): 检查请求所包含的 “Content-Type” 是否为给定的 type 值。 如果没有 request body,返回 undefined。 如果没有 content type,或者匹配失败,返回 false。 否则返回匹配的 content-type
    // When Content-Type is application/json
    ctx.is('json', 'urlencoded'); // => 'json'
    ctx.is('application/json'); // => 'application/json'
    ctx.is('html', 'application/*'); // => 'application/json'
    
    ctx.is('html'); // => false
    
  11. request.charset:获取请求 charset(例"utf-8"),没有则返回 undefined
  12. request.query:将查询参数字符串进行解析并以对象的形式返回,如果没有查询参数字字符串则返回一个空对象,或根据给定的对象设置查询参数字符串。注意,该方法不支持嵌套解析
  13. request.fresh:检查请求缓存是否 “fresh”(内容没有发生变化)。该方法用于在 If-None-Match / ETag, If-Modified-Since 和 Last-Modified 中进行缓存协调。当在 response headers 中设置一个或多个上述参数后,该方法应该被使用
  14. request.stale:与 req.fresh 相反
  15. request.protocol:返回请求协议,“https” 或者 “http”。 当 app.proxy 设置为 true 时,支持 X-Forwarded-Host
  16. request.socket:返回请求的 socket
  17. request.get(field):返回请求头中 field 字段的值

5. response 对象

Koa Response 对象是对 node 的 response 进一步抽象和封装,提供了日常 HTTP 服务器开发中一些有用的功能,常用api有:

  1. response.socket:响应套接字(套接字就是 socket),作为 request.socket 指向 net.Socket 实例
  2. response.header:响应头对象(response.headers 等价)
  3. response.status:获取响应状态(默认情况下,response.status设置为404,而不像node’s res.statusCode默认为200),或通过数字设置响应状态
  4. response.message:获取响应状态消息(默认情况下, response.message关联response.status),或将响应状态消息设置为给定值
  5. response.body:获取响应体,或设置响应体(如果此时 res.status 没有赋值,Koa会自动设置为 200 或 204)
  6. response.length:以数字返回响应的 Content-Length,或者从ctx.body推导出来,或者undefined,或将响应的 Content-Length 设置为给定值
  7. response.set(field, value):设置 response header 字段 field 的值为 value
  8. response.append(field, value):添加额外的字段 field 的值为 val
  9. response.set(fields):使用对象同时设置 response header 中多个字段的值
  10. response.remove(field):移除 response header 中字段 filed
  11. response.type:获取 response Content-Type,不包含像"charset"这样的参数,或通过 mime 类型的字符串或者文件扩展名设置 response Content-Type
  12. response.redirect(url, [alt]):执行 [302] 重定向到 url,如果想要修改默认的 [302] 状态码,直接在重定向之前或者之后执行即可。如果要修改 body,需要在重定向之前执行
    【字符串 “back” 是特殊参数,其提供了 Referrer 支持。当没有 Referrer 时,使用 alt 或者 / 代替】
    ctx.redirect('back');
    ctx.redirect('back', '/index.html');
    ctx.redirect('/login');
    ctx.redirect('http://google.com');
    
  13. response.headerSent:检查 response header 是否已经发送,用于在发生错误时检查客户端是否被通知
  14. response.lastModified:如果存在 Last-Modified,则以 Date 的形式返回,或以 UTC 格式设置 Last-Modified,可以使用 Date 或 date 字符串来进行设置

6. koa1,koa2 和 express 的区别

  1. 实现异步方式不同,koa1 实现异步是通过 generator/yield,koa2 实现异步是通过 async/awaite,而 express 实现异步是通过回调函数的方式
  2. express 是大而全,内置了大多数的中间件,更让人省心,koa2 不绑定任何的框架,干净简洁,小而精,更容易实现定制化,扩展性好,koa 中想实现 express 很多功能需要借助第三方中间件解决
    在这里插入图片描述
  3. express 本身是不支持洋葱模型的数据流入流出能力的(类似于线型),需要引入其他的插件,而在 koa 中,一切的流程都是中间件,数据流向遵循洋葱模型,先入后出,是按照类似堆栈的方式组织和执行的,koa 的数据流入流出,next() 后,会进入下一个中间件并执行,然后从最后一个中间件反向执行
    const Koa = require('koa')
    const app = new Koa()
    
    const mid1 = async (ctx, next) => {
        ctx.body =  '前:' + '1\n'
        await next()
        ctx.body =   ctx.body + '后:' + '1\n'
    }
    
    const mid2 = async (ctx, next) => {
        ctx.body =    ctx.body + '前:'+ '2\n'
        await next()
        ctx.body =    ctx.body + '后:'+ '2\n'
    }
    
    const mid3 = async (ctx, next) => {
        ctx.body =  ctx.body + '前:'+  '3\n'
        await next()
        ctx.body =   ctx.body + '后:'+ '3\n'
    }
    
    app.use(mid1)
    app.use(mid2)
    app.use(mid3)
    
    app.listen(3000)
    
    // 前1
    // 前2
    // 前3
    // 后3
    // 后2
    // 后1
    
  4. koa 新增 context 对象,作为这次请求的上下文对象,除了提供了大量便捷的 api 辅助开发,还可以在其上面保存一些公有的参数数据来使用

猜你喜欢

转载自blog.csdn.net/m0_52212261/article/details/128345228