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请求,该回调函数可以传入两个参数,依次通常写作 ctx
、 next
。 ctx
可以看成是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
对象可用的一些属性和方法如下:
属性和方法 | 说明 | 备注 |
---|---|---|
req | Node.js HTTP模块的 request 对象 | |
res | Node.js HTTP模块的 response | 不支持以下属性和方法: res.statusCode res.writeHead() res.write() res.end() |
request | Koa 的 Request 对象 | |
response | Koa 的 Response 对象 | |
state | 推荐的用于全局传递数据的命名空间 | |
app | Koa应用的实例引用 | |
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:基础入门的主要内容,如果未能解决你的问题,请参考以下文章