本文为我个人对Koa官网语法介绍的学习笔记,部分小节复制粘贴自官网。
安装Koa,官网有很明确的介绍,直接在项目目录下终端中运行npm i koa
就行。
Koa概念目录
1. Koa概念
官网将Koa相关知识分为:
- 应用(Application)
- 上下文(Context)
- 请求(Request)
- 响应(Responds)
2. 应用程序
Koa应用程序是一个包含一组中间件函数的对象,它是按照类似堆栈的方式组织和执行的。
2.1 Koa洋葱模型(级联)
Koa中间件使用传统的方式级联,使用async/await
来实现。下图为Koa的洋葱模型。
参考官网所给示例:
const Koa = require('koa');
const app = new Koa();
// logger
app.use(async (ctx, next) => {
await next(); // 请求到达此处后,跳转到下一个中间件x-response-time
const rt = ctx.response.get('X-Response-Time');
console.log(`${ctx.method} ${ctx.url} - ${rt}`);
});
// x-response-time
app.use(async (ctx, next) => {
const start = Date.now();
await next(); // 请求流执行到此处,跳转到下一个中间件response
// response中间件执行完成后,继续执行下面代码。下面代码执行完成后回到上一个中间件回调函数处。
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
});
// response
app.use(async ctx => {
ctx.body = 'Hello World'; // 请求流到此处,执行完成,回到上一个中间件回调函数处。
});
app.listen(3000);
2.2 应用程序设置
应用程序设置是 app 实例上的属性。
应用程序设置包括:
app.env
app.keys
app.proxy
app.proxyIpHeader
app.maxIpsCount
应用程序设置有两种方式:
- 第一种:在初始化app实例时,将设置传递给构造函数;
- 第二种:初始化app实例完成后,动态的设置app实例上的属性;
2.3 常用的应用程序设置
app.listen()
:Koa应用程序不是HTTP服务器的1对1展现,因此可以将同一个程序作为HTTP和HTTPS或多个地址,其是下面代码的语法糖:
const http = require('http');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
app.callback()
:返回适用于http.createServer()
方法的回调函数用来处理请求,也可以用此回调函数将Koa应用程序挂载到Connect/Express
应用程序中。
app.use(function)
:将括号中的中间件方法添加到此应用程序。app.use()
返回this,因此可以链式表达。
app.use(someMiddleware)
app.use(someOtherMiddleware)
app.listen(3000)
// 下面代码效果与上面代码实现效果相同
app.use(someMiddleware)
.use(someOtherMiddleware)
.listen(3000)
app.keys
:设置签名的 Cookie 密钥。
// 传递给KeyGrip
app.keys = ['im a newer secret', 'i like turtle'];
app.keys = new KeyGrip(['im a newer secret', 'i like turtle'], 'sha256');
app.context
:即上下文,从app.context
创建ctx
的原型,可以通过编辑 app.context 为 ctx 添加其他属性。
2.4 错误处理
默认情况下,将所有错误输出到 stderr,除非 app.silent 为 true。 当 err.status 是 404 或 err.expose 是 true 时默认错误处理程序也不会输出错误。
要执行自定义错误处理逻辑,如集中式日志记录,您可以添加一个 “error” 事件侦听器:
app.on('error', err => {
log.error('server error', err)
});
如果在请求/响应期间出现错误,则无法响应客户端,但是Context
实例仍然被传递:
app.on('error', (err, ctx) => {
log.error('server error', err, ctx)
});
如果发生错误,但是可以响应客户端,且没有数据被写入socket中,则Koa将用“内部服务器错误”(500)进行响应。
3. 上下文
Koa Context 将 node 的 request 和 response 对象封装到单个对象中,为编写 Web 应用程序和 API 提供了许多有用的方法。 这些操作在 HTTP 服务器开发中频繁使用,它们被添加到此级别而不是更高级别的框架,这将强制中间件重新实现此通用功能。
// 每一个请求都将创建一个Context,并且在中间件中作为接收器引用(ctx标识符)
app.use(async ctx => {
ctx; // 这是 Context
ctx.request; // 这是 koa Request
ctx.response; // 这是 koa Response
})
3.1 常用API
ctx.req
:Node 的 request 对象;
ctx.res
:Node 的 response 对象;
ctx.request
:koa 的 Request 对象;
ctx.response
:koa 的 Response 对象;
ctx.state
:推荐的命名空间,用于通过中间件传递信息和你的前端视图;
ctx.app
:应用程序实例引用;
ctx.app.emit
:Koa 应用扩展了内部 EventEmitter。ctx.app.emit 发出一个类型由第一个参数定义的事件。对于每个事件,您可以连接 “listeners”,这是在发出事件时调用的函数。
ctx.cookies.get(name, [options])
:通过 options 获取 cookie name;
ctx.cookies.set(name, value, [options])
:通过 options 设置 cookie name 的 value;
ctx.throw([status], [msg], [properties])
:用来抛出一个包含 .status 属性错误的帮助方法,其默认值为 500;
ctx.assert(value, [status], [msg], [properties])
:当 !value
时抛出一个类似 .throw 错误的帮助方法。这与 node 的 assert() 方法类似.
3.2 Request 别名
以下访问器和 Request 别名等效:
- ctx.header
- ctx.headers
- ctx.method
- ctx.method=
- ctx.url
- ctx.url=
- ctx.originalUrl
- ctx.origin
- ctx.href
- ctx.path
- ctx.path=
- ctx.query
- ctx.query=
- ctx.querystring
- ctx.querystring=
- ctx.host
- ctx.hostname
- ctx.fresh
- ctx.stale
- ctx.socket
- ctx.protocol
- ctx.secure
- ctx.ip
- ctx.ips
- ctx.subdomains
- ctx.is()
- ctx.accepts()
- ctx.acceptsEncodings()
- ctx.acceptsCharsets()
- ctx.acceptsLanguages()
- ctx.get()
3.3 Response 别名
- ctx.body
- ctx.body=
- ctx.status
- ctx.status=
- ctx.message
- ctx.message=
- ctx.length=
- ctx.length
- ctx.type=
- ctx.type
- ctx.headerSent
- ctx.redirect()
- ctx.attachment()
- ctx.set()
- ctx.append()
- ctx.remove()
- ctx.lastModified=
- ctx.etag=
4. 请求(Request)
Koa Request 对象是在 node 的原生请求对象之上的抽象,提供了诸多对 HTTP 服务器开发有用的功能。
4.1 API
5. 响应(Response)
Koa Response 对象是在 node 的原生响应对象之上的抽象,提供了诸多对 HTTP 服务器开发有用的功能。
5.1 响应头API
响应头对象:response.header
或response.headers
;
响应套接字为:response.socket
,指向Node中net.Socket
实例;
5.2 响应状态与响应信息API
获取响应状态:response.status
,默认情况下,response.status 设置为 404 而不是像 node 的 res.statusCode 那样默认为 200。
设置响应状态:response.status=
,常见状态码:
- 100 “continue”
- 101 “switching protocols”
- 102 “processing”
- 200 “ok”
- 201 “created”
- 202 “accepted”
- 203 “non-authoritative information”
- 204 “no content”
- 205 “reset content”
- 206 “partial content”
- 207 “multi-status”
- 208 “already reported”
- 226 “im used”
- 300 “multiple choices”
- 301 “moved permanently”
- 302 “found”
- 303 “see other”
- 304 “not modified”
- 305 “use proxy”
- 307 “temporary redirect”
- 308 “permanent redirect”
- 400 “bad request”
- 401 “unauthorized”
- 402 “payment required”
- 403 “forbidden”
- 404 “not found”
- 405 “method not allowed”
- 406 “not acceptable”
- 407 “proxy authentication required”
- 408 “request timeout”
- 409 “conflict”
- 410 “gone”
- 411 “length required”
- 412 “precondition failed”
- 413 “payload too large”
- 414 “uri too long”
- 415 “unsupported media type”
- 416 “range not satisfiable”
- 417 “expectation failed”
- 418 “I’m a teapot”
- 422 “unprocessable entity”
- 423 “locked”
- 424 “failed dependency”
- 426 “upgrade required”
- 428 “precondition required”
- 429 “too many requests”
- 431 “request header fields too large”
- 500 “internal server error”
- 501 “not implemented”
- 502 “bad gateway”
- 503 “service unavailable”
- 504 “gateway timeout”
- 505 “http version not supported”
- 506 “variant also negotiates”
- 507 “insufficient storage”
- 508 “loop detected”
- 510 “not extended”
- 511 “network authentication required”
获取响应消息:response.message
,将响应的状态消息设置为给定值:response.message=
。