Koa笔记 01:基础入门

Posted Naisu Xu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Koa笔记 01:基础入门相关的知识,希望对你有一定的参考价值。

目的

Node.js最基本的是用来搭建HTTP服务器使用,它内置的模块基本上可以满足基础的HTTP服务器功能,但是如果要实现比较完整的HTTP服务器功能体验的话开发者还需要编写更多的代码。所以通常使用的话可以选择现成的框架,Koa就是一个现在比较流行的框架。这篇文章将对Koa使用做个入门介绍。

Koa 通过 node.js 实现了一个十分具有表现力的 HTTP 中间件框架,力求让 Web 应用开发和 API 使用更加地愉快。Koa 的中间件之间按照编码顺序在栈内依次执行,允许您执行操作并向下传递请求(downstream),之后过滤并逆序返回响应(upstream)。


几乎所有 HTTP 服务器通用的方法都被直接集成到 Koa 大约570行源码的代码库中。其中包括内容协商,节点不一致性的规范化,重定向等等操作。


Koa没有捆绑任何中间件。

官网地址:https://koajs.com/
项目地址:https://github.com/koajs/koa

基础介绍

Koa 依赖 Node.js v7.6.0 或 ES2015及更高版本和 async 方法支持,在安装了Node.js、建立并初始化项目后就可以使用npm安装Koa:npm install koa ,目前Koa版本为 2.13.4

下面是个最基本的Koa使用:

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

// response
app.use(ctx => {
  ctx.body = 'Hello Koa';
});

app.listen(3000);

Koa最重要的一点就是它是一个 HTTP 中间件框架 ,这是Koa最重要的一点,只要理解这点Koa就算入门了。Koa是基于HTTP功能的,首先看下Node.js中http模块的使用:

上面的演示和前面Koa的演示结构上是很像的,无非就是编写相应的HTTP请求处理方法,然后启动监听,我们写代码主要就是关注于中间处理部分。事实上前面的Koa演示的代码也可以写成下面这样:

const http = require('http');
const Koa = require('koa');

const app = new Koa();

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

http.createServer(app.callback()).listen(3000); // 相当于 app.listen(3000);

到这里就可以认识到Koa就是在http模块模块的基础上接管了来自客户端的HTTP请求,接下来所有操作就都是在Koa的基础上进行了。

Koa对象的use方法中可以传入回调函数用来处理来自客户端的HTTP请求,该回调函数可以传入两个参数,依次通常写作 ctxnextctx 可以看成是HTTP请求和响应的整体封装,而 next 为下一步的异步处理。

Koa对于每个HTTP请求都可以分为多步来处理, 也就是多可以有多个 app.use() ,实际处理时按照调用 app.use() 的先后顺序执行,并且在每个 app.use() 的回调函数中又可以以异步方式调用下一步处理。下面是个简单的演示:

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

app.use(async (ctx, next) => {
    console.log('1');
    await next();
    console.log('5');
});

app.use(async (ctx, next) => {
    console.log('2');
    await next();
    console.log('4');
});

app.use(ctx => {
    console.log('3');
    ctx.body = 'Hello Koa';
});

app.listen(3000);

Koa的对象除了上面出现的 use() 、 listen() 、 callback() 方法外,常用的还有 keys 、 context 对象 和 错误处理。 keys 对象用于设置 signed cookie keys,比如下面两种方式:

app.keys = ['im a newer secret', 'i like turtle'];
app.keys = new KeyGrip(['im a newer secret', 'i like turtle'], 'sha256');

context 对象是我们最常用的对象了,一般在使用时变量名为 ctx ,它封装了http请求和响应等内容。你也可以向其中添加属性共全局使用。 context 对象内容比较多,将再下一节单独介绍。

错误处理相关内容将在再下面一节进行介绍。

Koa提供的功能几乎就是上面介绍的这些部分了,它本身提供的功能并不多,很多功能都需要依靠各种中间件来实现。Koa的中间件就是一个个的函数,在 app.use() 中被调用。根据Koa的机制,每个HTTP请求可以使用多个中间件分步进行处理。

Koa Context

Koa的 context 对象是我们最常用的对象,一般在使用时变量名为 ctx ,它封装了http请求和响应等内容,比如 ctx.req 就是 Node.js HTTP模块的 request 对象,ctx.res 就是 Node.js HTTP模块的 response 对象。 context 对象可用的一些属性和方法如下:

属性和方法说明备注
reqNode.js HTTP模块的 request 对象
resNode.js HTTP模块的 response不支持以下属性和方法:
res.statusCode
res.writeHead()
res.write()
res.end()
requestKoa 的 Request 对象
responseKoa 的 Response 对象
state推荐的用于全局传递数据的命名空间
appKoa应用的实例引用
cookies.get(name, [options])获得 cookie 中名为 name 的值,options 为可选参数例:ctx.cookies.get(‘name’, { signed: true });
signed 为 true,表示需要密钥
cookies.set(name, value, [options])设置 cookie 中名为 name 的值,options 为可选参数
throw([status], [msg], [properties])抛出异常
assert(value, [status], [msg], [properties])当 !value 时抛出类似于throw()方式的错误
respond时用res时可以设置respond = false不推荐

Request

Koa Request 对象是对 node 的 request 进一步抽象和封装,提供了日常 HTTP 服务器开发中一些有用的功能。Koa Request 大多数属性支持简写,比如 ctx.request.headers 等价于 ctx.headers

属性和方法说明备注
header / header=
headers / headers=
获取 / 设置 请求头对象
method / method=获取 / 设置 请求方法
length返回Content-Length数值
url / url=获取 / 设置 url
originalUrl获取请求原始URL
origin获取原始URL,包含 protocol 和 host
href获取完整的请求URL, 包含 protocol, host 和 url
path / path=获取 / 设置 请求路径(保留当前查询字符串)
querystring / querystring=获取 / 设置 原始查询字符串(不包含?)
search / search=获取 / 设置 原始查询字符串(包含?)
host获取host(hostname:port)
hostname获取 hostname
URL获取 WHATWG 解析的URL对象
type获取请求 Content-Type
charset获取请求 charset,没有则返回 undefined:
query将查询参数字符串进行解析并以对象的形式返回
如果没有查询参数字字符串则返回一个空对象
query=根据给定的对象设置查询参数字符串
fresh检查请求缓存是否 “fresh”(内容没有发生变化)
stale与 fresh 相反
protocol返回请求协议,“https” 或者 “http”
secure简化版 protocol == “https”,用来检查请求是否通过 TLS 发送
ip返回请求远程ip地址
ips返回路径上依次的ip地址
subdomains以数组形式返回子域名
is(types…)检查请求所包含的 “Content-Type” 是否为给定的 type 值,
如果没有 request body,返回 undefined,
如果没有 content type,或者匹配失败,返回 false,
否则返回匹配的 content-type
accepts(types)检查给定的类型 types(s) 是否可被接受,当为 true 时返回最佳匹配,否则返回 false
acceptsEncodings(encodings)检查 encodings 是否可以被接受,当为 true 时返回最佳匹配,否则返回 false
acceptsCharsets(charsets)检查 charsets 是否可以被接受,如果为 true 则返回最佳匹配, 否则返回 false
acceptsLanguages(langs)检查 langs 是否可以被接受,如果为 true 则返回最佳匹配,否则返回 false
idempotent检查请求是否为幂等
socket返回请求的socket
get(field)返回请求头

Response

Koa Response 对象是对 node 的 response 进一步抽象和封装,提供了日常 HTTP 服务器开发中一些有用的功能。Koa Response 大多数属性支持简写,比如 ctx.response.body 等价于 ctx.body

属性和方法说明备注
header / headers响应头对象不支持简写
socket响应socket不支持简写
status / status=获取 / 设置 响应状态,默认为404
message / message=获取 / 设置 响应状态消息
length / length=获取 / 设置 响应 Content-Length 数值,没有则返回undefined
body / body=获取 / 设置 响应正文
get(field) / set(field, value)获取 / 设置 响应头中字段
append(field, value)向响应头添加额外字段
set(fields)使用对象设置响应头多个字段
remove(field)移除响应头中的字段
type / type=获取 / 设置 Content-Type
is(types…)检查响应类型是否是所提供的类型之一不支持简写
redirect(url, [alt])执行 [302] 重定向到对应 url
attachment([filename])设置 “attachment” 的 Content-Disposition,用于给客户端发送信号来提示下载,
filename 为可选参数,用于指定下载文件名
headerSent检查 response header 是否已经发送,用于在发生错误时检查客户端是否被通知
lastModified / lastModified=获取 / 设置 lastModified
etag=设置 包含 "s 的 ETag
vary(field)不支持简写
flushHeaders()不支持简写

错误处理

Koa对象可以使用下面的方式捕获异常:

app.on('error', err => {
    console.error('error', err);
});

// 错误发生在 请求/响应 环节
app.on('error', (err, ctx) => {
    console.error('error', err, ctx)
});

对于发生在 请求/响应 环节的错误也可以使用 try { } catch { } 进行捕获,这种方式捕获的错误不会再传递给上面的onerror事件,如果有需求可以使用Koa对象的emit()方法释放捕获的错误:

app.use(async (ctx, next) => {
    try {
        await next();
    } catch (err) {
        console.error('error', err);
        ctx.app.emit('error', err, ctx);
    }
});

在 请求/响应 环节中可以使用 throw([status], [msg], [properties]) 来抛出异常。

下面是个错误处理的演示:

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

app.use(async (ctx, next) => {
    try {
        await next();
    } catch (err) {
        console.error('error 1', err);
        ctx.app.emit('error', err, ctx);
    }
});

app.use(ctx => {
    ctx.throw(500);
});

app.on('error', (err, ctx) => {
    console.error('error 2', err)
});

app.listen(3000);

总结

本篇文章基本介绍完了Koa本体所涉及的大部分功能,Koa是一个中间件框架,主要提供的功能也并不多,更多Web服务器常用的功能比如 路由、静态文件、模板 等功能都需要通过中间件来提供。接下来的文章会介绍些常用的中间件及使用方法。

以上是关于Koa笔记 01:基础入门的主要内容,如果未能解决你的问题,请参考以下文章

《Koa.js 设计模式-学习笔记》Koa.js第二本开源电子书完结

koa2 从入门到进阶之路

01-koa2基础

koa入门3-6

SpringBoot 学习笔记01—Spring基础入门

《Koa2进阶学习笔记》完结