应用程序(Application)
Koa 应用程序是一个包含一组中间件函数的对象,它是按照类似堆栈的方式组织和执行的。
一个关键的设计点是在其低级中间件层中提供高级“语法糖”。
这包括诸如内容协商,缓存清理,代理支持和重定向等常见任务的方法。 尽管提供了相当多的有用的方法 Koa 仍保持了一个很小的体积,因为没有捆绑中间件。
级联
通过中间件一系列功能直接传递控制,直到一个返回,Koa 调用“下游”,然后控制流回“上游”。
// 当一个中间件调用 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);
设置
- app.env 默认是 NODE_ENV 或 “development”
- app.proxy 当真正的代理头字段将被信任时
- app.subdomainOffset 对于要忽略的 .subdomains 偏移[2]
app.listen()
const Koa = require('koa');
const app = new Koa();
app.listen(3000);
上面的语法为下面的语法糖
const http = require('http');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
可以将同一个应用程序同时作为 HTTP 和 HTTPS 或多个地址
const http = require('http');
const https = require('https');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
https.createServer(app.callback()).listen(3001);
app.callback()
返回适用于 http.createServer() 方法的回调函数来处理请求。你也可以使用此回调函数将 koa 应用程序挂载到 Connect/Express 应用程序中
app.use(function)
将给定的中间件方法添加到此应用程序
app.keys=
设置签名的 Cookie 密钥
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.db = db();
app.use(async ctx => {
console.log(ctx.db);
});
错误处理
app.on('error', (err, ctx) => {
log.error('server error', err, ctx)
});
上下文(Context)
Koa Context 将 node 的 request 和 response 对象封装到单个对象中,为编写 Web 应用程序和 API 提供了许多有用的方法。
每个 请求都将创建一个 Context,并在中间件中作为接收器引用,或者 ctx 标识符
API
ctx.req
Node 的 request 对象.
ctx.res
Node 的 response 对象,koa中不支持node属性
- res.statusCode
- res.writeHead()
- res.write()
- res.end()
ctx.request
koa 的 Request 对象
ctx.response
koa 的 Response 对象
ctx.state
推荐的命名空间,用于通过中间件传递信息
ctx.state.user = await User.find(id)
ctx.app
应用程序实例引用
ctx.cookies.get(name, [options])
通过 options 获取 cookie name
- signed 所请求的cookie应该被签名
ctx.cookies.set(name, value, [options])
- maxAge 一个数字表示从 Date.now() 得到的毫秒数
- signed cookie 签名值
- expires cookie 过期的 Date
- path cookie 路径, 默认是’/’
- domain cookie 域名
- secure 安全 cookie
- httpOnly 服务器可访问 cookie, 默认是 true
- overwrite 一个布尔值,表示是否覆盖以前设置的同名的 cookie (默认是 false). 如果是 true, 在同一个请求中设置相同名称的所有 Cookie(不管路径或域)是否在设置此Cookie 时从 Set-Cookie 标头中过滤掉。
koa 使用传递简单参数的 cookies 模块
ctx.throw([status], [msg], [properties])
Helper 方法抛出一个 .status 属性默认为 500 的错误
koa 使用 http-errors 来创建错误
ctx.assert(value, [status], [msg], [properties])
koa 使用 http-assert 作为断言
Request 别名
- ctx.header 请求标头对象
- ctx.headers 请求标头对象。等价于 request.header
- 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()
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=
请求(Request)
ctx.request = {
header
headers // 别名为 request.header
method
length // 返回以数字返回请求的 Content-Length,或 undefined
url // 获取请求 URL.
originalUrl // 获取请求原始URL
origin // 获取URL的来源,包括 protocol 和 host
href // 获取完整的请求URL,包括 protocol,host 和 url
path. // 获取请求路径名
querystring // 根据 ? 获取原始查询字符串
search. // 使用 ? 获取原始查询字符串
host. // 获取当前主机(hostname:port)。当 app.proxy 是 true 时支持 X-Forwarded-Host,否则使用 Host。
hostname // 存在时获取主机名。当 app.proxy 是 true 时支持 X-Forwarded-Host,否则使用 Host。
URL // 获取 WHATWG 解析的 URL 对象。
type // 获取请求 Content-Type 不含参数 "charset"。
charset // 在存在时获取请求字符集,或者 undefined
query. // 获取解析的查询字符串, 当没有查询字符串时,返回一个空对象
fresh // 检查请求缓存是否“新鲜”,也就是内容没有改变。此方法用于 If-None-Match / ETag, 和 If-Modified-Since 和 Last-Modified 之间的缓存协商。 在设置一个或多个这些响应头后应该引用它。
stale // 相反与 request.fresh
protocol // 返回请求协议,“https” 或 “http”。当 app.proxy 是 true 时支持 X-Forwarded-Proto
secure // ctx.protocol == "https" 来检查请求是否通过 TLS 发出
ip. // 请求远程地址。 当 app.proxy 是 true 时支持 X-Forwarded-Proto
ips // 当 X-Forwarded-For 存在并且 app.proxy 被启用时,这些 ips 的数组被返回,从上游 - >下游排序。 禁用时返回一个空数组。
subdomains // 将子域返回为数组
is(types...) // 检查传入请求是否包含 Content-Type 头字段
accepts(types) // 检查给定的 type(s) 是否可以接受
acceptsEncodings(encodings) // 'gzip', 'deflate', 'identity'
acceptsCharsets(charsets) // 检查 charsets 是否可以接受
acceptsLanguages(langs)
idempotent // 检查请求是否是幂等的
socket // 返回请求套接字
get(field) // 返回请求标头
}
fresh使用
// 新鲜度检查需要状态20x或304
ctx.status = 200;
ctx.set('ETag', '123');
// 缓存是最新的
if (ctx.fresh) {
ctx.status = 304;
return;
}
// 缓存是陈旧的
// 获取新数据
ctx.body = await db.find('something');
响应(Response)
Koa Response 对象是在 node 的 vanilla 响应对象之上的抽象,提供了诸多对 HTTP 服务器开发有用的功能
ctx.response = {
header // 响应标头对象
headers // 响应标头对象,等价于上面的
socket // 请求套接字
status // 获取响应状态。默认情况下,response.status 设置为 404 而不是像 node 的 res.statusCode 那样默认为 200。
message // response.message 与 response.status 关联
length // 将响应的 Content-Length 设置为给定值。
body // 主体
get(field) // const etag = ctx.response.get('ETag')
set(field, value) // ctx.set('Cache-Control', 'no-cache')
set(fields)
append(field, value) // 附加额外的标头 field ctx.append('Link', '<http://127.0.0.1/>')
remove(field)
type // 获取响应 Content-Type 不含参数 "charset"
is(types...) // 非常类似 ctx.request.is(). 检查响应类型是否是所提供的类型之一。这对于创建操纵响应的中间件特别有用
redirect(url, [alt]) // 执行 [302] 重定向到 url
attachment([filename]) // 将 Content-Disposition 设置为 “附件” 以指示客户端提示下载。(可选)指定下载的 filename。
headerSent // 检查是否已经发送了一个响应头。 用于查看客户端是否可能会收到错误通知
lastModified // 将 Last-Modified 标头返回为 Date, 如果存在。
etag= // 设置包含 " 包裹的 ETag 响应, 请注意,没有相应的 response.etag getter
vary(field) // 在 field 上变化
flushHeaders() // 刷新任何设置的标头,并开始主体
}
1213

被折叠的 条评论
为什么被折叠?



