打开koa中文网站发现域名备案出了点问题,花了一下午时间翻译了一份中文手册。如有啥不对的地方还请各位大佬指出。
翻译时间:2022年10月11日
官网地址:koajs.com/
Introduction
Koa 是由 Express 背后的团队设计的新 Web 框架,旨在为 Web 应用程序和 API 提供更小、更具表现力和更强大的基础。通过利用异步函数,Koa 允许您放弃回调并大大增加错误处理能力。Koa 没有在其核心中捆绑任何中间件,它提供了一套优雅的方法,使编写服务器变得快速而愉快。
Installation
ps: node版本需大于7.6.0
$ nvm install 7
$ npm i koa -S
$ node my-koa-app.js
Application
Koa 应用程序是一个对象,其中包含一组中间件函数,这些函数在请求时以类似堆栈的方式组合和执行。Koa 类似于您可能遇到的许多其他中间件系统,例如 Ruby 的 Rack、Connect 等 - 但是做出了一个关键设计决策,即在其他低级中间件层提供高级“糖”。这提高了互操作性、健壮性,并使编写中间件更加愉快。
这包括内容协商、缓存新鲜度、代理支持和重定向等常见任务的方法。尽管提供了相当多的有用方法,但 Koa 的占用空间很小,因为没有捆绑中间件。
强制性的 hello world 应用程序:
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
Cascading
Koa 中间件以更传统的方式级联,你可能习惯于使用类似的工具——这在以前很难通过节点使用回调使用户友好。然而,通过异步函数,我们可以实现“真正的”中间件。对比 Connect 的实现,它简单地通过一系列函数传递控制直到一个返回,Koa 调用“下游”,然后控制流回到“上游”。
以下示例以“Hello World”响应,但首先请求流经 x-response-time 和日志中间件以标记请求何时开始,然后通过响应中间件产生控制权。当中间件调用 next() 时,函数会挂起并将控制权传递给定义的下一个中间件。在没有更多的中间件在下游执行之后,堆栈将展开,每个中间件都恢复执行其上游行为。
const Koa = require('koa');
const app = new Koa();
// logger
app.use(async (ctx, next) => {
await next();
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();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
});
// response
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
Settings
应用程序配置是应用程序实例上的属性,目前支持以下内容:
- app.env 默认为 NODE_ENV 或“development”
- app.keys 签名的 cookie 密钥数组
- app.proxy 当真正的代理标头字段将被信任时
- app.subdomainOffset 要忽略的 .subdomains 偏移量,默认为 2
- app.proxyIpHeader 代理ip头,默认为X-Forwarded-For
- app.maxIpsCount 从代理ip头读取的最大ips,默认为0(表示无穷大)
const Koa = require('koa');
// 通过构造函数
const app = new Koa({ proxy: true });
// 动态设置
app.env = 'development'
app.listen(...)
Koa 应用程序不是 HTTP 服务器的一对一表示。可以将一个或多个 Koa 应用程序安装在一起,以使用单个 HTTP 服务器形成更大的应用程序。
创建并返回一个 HTTP 服务器,将给定的参数传递给 Server#listen()。这些参数记录在 nodejs.org 上。下面是一个绑定到 3000 端口的无用 Koa 应用:
const Koa = require('koa');
const app = new Koa();
app.listen(3000);
app.listen(...) 方法只是以下内容的糖:
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() 方法处理请求的回调函数。你也可以使用这个回调函数在 Connect/Express 应用中挂载你的 Koa 应用。
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,但是您也可以传递您自己的 KeyGrip 实例。例如以下是可以接受的:
app.keys = ['OEK5zjaAMPc3L6iK7PyUjCOziUH3rsrMKB9u8H07La1SkfwtuBoDnHaaPCkG5Brg', 'MNKeIebviQnCPo38ufHcSfw3FFv8EtnAe1xE02xkN1wkCV1B2z126U44yk2BQVK7'];
app.keys = new KeyGrip(['OEK5zjaAMPc3L6iK7PyUjCOziUH3rsrMKB9u8H07La1SkfwtuBoDnHaaPCkG5Brg', 'MNKeIebviQnCPo38ufHcSfw3FFv8EtnAe1xE02xkN1wkCV1B2z126U44yk2BQVK7'], 'sha256');
出于安全原因,请确保密钥足够长且随机。
在使用 { signed: true } 选项签署 cookie 时,这些密钥可以被轮换和使用:
ctx.cookies.set('name', 'tobi', { signed: true });
app.context
app.context 是创建 ctx 的原型。您可以通过编辑 app.context 向 ctx 添加其他属性。这对于向 ctx 添加要在整个应用程序中使用的属性或方法很有用,这可能会更高效(无中间件)和/或更容易(更少的 require()),但代价是更多地依赖 ctx,这可能是被认为是反模式。
例如,要从 ctx 添加对数据库的引用:
app.context.db = db();
app.use(async ctx => {
console.log(ctx.db);
});
ps:
- ctx 上的许多属性是使用 getter、setter 和 Object.defineProperty() 定义的。您只能通过在 app.context 上使用 Object.defineProperty() 来编辑这些属性(不推荐)。请参阅 https://github.com/koajs/koa/issues/652。
- 已挂载的应用程序当前使用其父级的 ctx 和设置。因此,挂载的应用程序实际上只是一组中间件。
Error Handling
默认情况下,除非 app.silent 为 true,否则将所有错误输出到 stderr。当 err.status 为 404 或 err.expose 为 true 时,默认错误处理程序也不会输出错误。要执行自定义错误处理逻辑,例如集中式日志记录,您可以添加一个“错误”事件侦听器:
app.on('error', err => {
log.error('server error', err)
});
如果req/res周期出错,无法响应客户端,也传递Context实例:
app.on('error', (err, ctx) => {
log.error('server error', err, ctx)
});
当发生错误并且仍然可以响应客户端时,即没有数据写入套接字时,Koa 将适当地响应 500“内部服务器错误”。在任何一种情况下,都会发出应用级别的“错误”以用于日志记录。
Context
Koa 上下文将节点的请求和响应对象封装到一个对象中,该对象为编写 Web 应用程序和 API 提供了许多有用的方法。这些操作在 HTTP 服务器开发中使用如此频繁,以至于它们被添加到此级别而不是更高级别的框架中,这将迫使中间件重新实现此通用功能。
每个请求都会创建一个上下文,并在中间件中作为接收者或 ctx 标识符引用,如下面的代码片段所示:
app.use(async ctx => {
ctx; // is the Context
ctx.request; // is a Koa Request
ctx.response; // is a Koa Response
});
为方便起见,许多上下文的访问器和方法只是委托给它们的 ctx.request 或 ctx.response 等效项,并且在其他方面是相同的。[例如 ctx.type 和 ctx.length 委托给response对象,而 ctx.path 和 ctx.method 委托给request。
API
上下文特定的方法和访问器。
ctx.req
Node的request对象
ctx.res
Node的response对象
不支持绕过 Koa 的响应处理。避免使用以下节点属性:
- 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
app实例引用
ctx.app.emit
Koa 应用程序扩展了一个内部 EventEmitter。 ctx.app.emit 发出一个类型由第一个参数定义的事件。对于每个事件,您可以连接“侦听器”,这是一个在事件发出时调用的函数。有关更多信息,请参阅错误处理文档。
ctx.cookies.get(name, [options])
使用选项获取 cookie 名称:
- signed 请求的 cookie 应该被签名
Koa 使用简单地传递选项的 cookies 模块。
ctx.cookies.set(name, value, [options])
使用选项将 cookie 名称设置为值:
-
maxAge:一个数字,表示从 Date.now() 到到期的毫秒数。
-
expires:一个 Date 对象,指示 cookie 的到期日期(默认在会话结束时到期)。
-
path:表示cookie路径的字符串(默认为/)。
-
domain:表示cookie域的字符串(无默认值)。
-
secure:一个布尔值,指示 cookie 是否仅通过 HTTPS 发送(HTTP 默认为 false,HTTPS 默认为 true)。
-
httpOnly:一个布尔值,指示 cookie 是否仅通过 HTTP(S) 发送,而不提供给客户端 JavaScript(默认为 true)。
-
sameSite:一个布尔值或字符串,指示 cookie 是否为“相同站点”cookie(默认为 false)。这可以设置为“strict”、“lax”、“none”或 true(映射到“strict”)。]
-
signed:一个布尔值,指示是否要对 cookie 进行签名(默认为 false)。如果为true,还将发送另一个带有 .sig 后缀的同名 cookie,其 27 字节的 url-safe base64 SHA1 值表示 cookie-name=cookie-value 与第一个 Keygrip 键的哈希值。
-
overwrite:一个布尔值,指示是否覆盖以前设置的同名cookie(默认为false)。如果为true,那么在设置此 cookie 时,在同一请求期间设置的所有具有相同名称(无论路径或域)的 cookie 都会从 Set-Cookie 标头中过滤掉。
Koa 使用简单地传递选项的 cookies 模块。
ctx.throw([status], [msg], [properties])
使用默认为 500 的 .status 属性引发错误的辅助方法,这将允许 Koa 做出适当的响应。允许以下组合:
ctx.throw(400);
ctx.throw(400, 'name required');
ctx.throw(400, 'name required', { user: user });
例如 ctx.throw(400, 'name required') 等价于:
const err = new Error('name required');
err.status = 400;
err.expose = true;
throw err;
请注意,这些是用户级错误,并用 err.expose 标记,这意味着这些消息适用于客户端响应,而错误消息通常不是这种情况,因为您不想泄露故障详细信息。
您可以选择传递一个属性对象,该对象按原样合并到错误中,用于修饰向上游请求者报告的机器友好错误。
ctx.throw(401, 'access_denied', { user: user });
Koa 使用 http-errors 来创建错误。 status 只能作为第一个参数传递。
ctx.assert(value, [status], [msg], [properties])
当 !value 时抛出类似于 ctx.throw() 的错误的辅助方法。 类似于节点的 assert() 方法。
ctx.assert(ctx.state.user, 401, 'User not found. Please login!');
Koa 使用 http-assert 进行断言。
ctx.respond
要绕过 Koa 的内置响应处理,您可以显式设置 ctx.respond = false;。如果您想写入原始 res 对象而不是让 Koa 为您处理响应,请使用此选项。
请注意,Koa 不支持使用它。这可能会破坏 Koa 中间件和 Koa 本身的预期功能。使用这个属性被认为是一种 hack,只是对那些希望在 Koa 中使用传统 fn(req, res) 函数和中间件的人来说是一种便利。
Request aliases
The following accessors and alias Request equivalents:
- 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()
Response aliases
The following accessors and alias Response equivalents:
- 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
Koa Request 对象是 node 的 vanilla request 对象之上的抽象,提供了对日常 HTTP 服务器开发有用的附加功能。
API
request.header
请求头对象。这与节点的 http.IncomingMessage 上的 headers 字段相同。
request.header=
设置请求头对象。
request.headers
请求头对象。别名为 request.header。
request.headers=
设置请求头对象。别名为 request.headers。
request.method
请求方法
request.method=
设置请求方法,对于实现methodOverride()等中间件很有用。
request.length
如果存在或未定义,则将请求 Content-Length 作为数字返回。
request.url
Get request URL.
request.url=
设置请求 URL,对 url 重写很有用。
request.originalUrl
获取请求原始 URL
request.origin
获取 URL 的来源,包括协议(protocol)和主机(host)。e.g.:http://example.com
request.href
获取完整的请求 URL,包括协议、主机和 url。e.g.:http://example.com/foo/bar?q=1
request.path
获取请求路径名。
request.path=
设置请求路径名并在存在时保留查询字符串。
request.querystring
获取没有 ? 的原始查询字符串。
request.querystring=
设置原始查询字符串。
request.search
获取带 ? 的原始查询字符串。
request.host
存在时获取主机(主机名:端口)。当 app.proxy 为 true 时支持 X-Forwarded-Host,否则使用 Host。
request.hostname
存在时获取主机名。当 app.proxy 为 true 时支持 X-Forwarded-Host,否则使用 Host。如果主机是 IPv6,Koa 将解析委托给 WHATWG URL API,注意这可能会影响性能。
request.URL
获取 WHATWG 解析的 URL 对象。
request.type
获取请求 Content-Type 没有“charset”等参数。e.g.:"image/png"
request.charset
在存在时获取请求字符集否则就是undefined。e.g.:"utf-8"
request.query
请注意,此 getter 不支持嵌套解析。e.g.:如果 querystring是"color=blue&size=small"
将会返回 { color: 'blue', size: 'small' }
request.query=
将查询字符串设置为给定对象。请注意,此设置器不支持嵌套对象。e.g.: ctx.query = { next: '/login' };
request.fresh
检查请求缓存是否“新鲜”,也就是内容没有改变。此方法用于 If-None-Match / ETag 和 If-Modified-Since 和 Last-Modified 之间的缓存协商。应在设置一个或多个这些响应标头后引用它。e.g.
// freshness check requires status 20x or 304
ctx.status = 200;
ctx.set('ETag', '123');
// cache is ok
if (ctx.fresh) {
ctx.status = 304;
return;
}
// cache is stale
// fetch new data
ctx.body = await db.find('something');
request.stale
与request.fresh相反
request.protocol
返回请求协议,“https”或“http”。当 app.proxy 为 true 时支持 X-Forwarded-Proto。
request.secure
ctx.protocol == 'https' 的简写,用于检查请求是否通过 TLS 发出。
request.ip
请求远程地址。当 app.proxy 为 true 时支持 X-Forwarded-For。
request.ips
当存在 X-Forwarded-For 并启用 app.proxy 时,将返回这些 ips 的数组,从上游 -> 下游排序。禁用时返回一个空数组。
例如,如果值为“client, proxy1, proxy2”,您将收到数组 ['client', 'proxy1', 'proxy2']。
大部分反向代理(nginx)通过proxy_add_x_forwarded_for设置x-forwarded-for,存在一定的安全风险。恶意攻击者可以通过伪造 X-Forwarded-Forrequest 标头来伪造客户端的 IP 地址。客户端发送的请求具有“伪造”的 X-Forwarded-For 请求标头。被反向代理转发后,request.ips 将是 ['forged', 'client', 'proxy1', 'proxy2']。
Koa 提供了两个选项来避免被绕过。
如果可以控制反向代理,可以通过调整配置避免绕过,或者使用koa提供的app.proxyIpHeader,避免读取x-forwarded-for获取ips。
const app = new Koa({
proxy: true,
proxyIpHeader: 'X-Real-IP',
});
如果你确切知道服务器前面有多少个反向代理,你可以通过配置 app.maxIpsCount 来避免读取用户的伪造请求头:
const app = new Koa({
proxy: true,
maxIpsCount: 1, // only one proxy in front of the server
});
// request.header['X-Forwarded-For'] === [ '127.0.0.1', '127.0.0.2' ];
// ctx.ips === [ '127.0.0.2' ];
request.subdomains
将子域作为数组返回。
子域是应用程序主域之前主机的点分隔部分。默认情况下,应用程序的域被假定为主机的最后两部分。这可以通过设置 app.subdomainOffset 来改变。
例如,如果域为“tobi.ferrets.example.com”:如果未设置 app.subdomainOffset(默认为2),则 ctx.subdomains 为 ['ferrets', 'tobi']。如果 app.subdomainOffset 为 3,则 ctx.subdomains 为 ['tobi']。
request.is(types...)
检查传入请求是否包含“Content-Type”标头字段,并且它包含任何给定的 mime 类型。如果没有请求正文,则返回 null。如果没有内容类型,或者匹配失败,则返回 false。否则,它返回匹配的内容类型。
// With Content-Type: text/html; charset=utf-8
ctx.is('html'); // => 'html'
ctx.is('text/html'); // => 'text/html'
ctx.is('text/*', 'text/html'); // => 'text/html'
// 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
例如,如果您想确保仅将图像发送到给定路由:
if (ctx.is('image/*')) {
// process
} else {
ctx.throw(415, 'images only!');
}
Content Negotiation
Koa 的请求对象包括由 Accept 和 Negotiator 提供支持的有用的内容协商实用程序。这些实用程序是:
- request.accepts(types)
- request.acceptsEncodings(types)
- request.acceptsCharsets(charsets)
- request.acceptsLanguages(langs)
如果未提供任何类型,则返回所有可接受的类型。
如果提供了多种类型,则将返回最佳匹配。如果未找到匹配项,则返回 false,并且您应该向客户端发送 406“不可接受”响应。
如果缺少可接受的任何类型的接受标头,则将返回第一个类型。因此,您提供的类型的顺序很重要。
request.accepts(types)
检查给定类型是否可接受,如果为true则返回最佳匹配,否则为false。type 值可以是一个或多个 mime 类型字符串,如“application/json”,扩展名如“json”,或数组[“json”,“html”,“text/plain”]。
// Accept: text/html
ctx.accepts('html');
// => "html"
// Accept: text/*, application/json
ctx.accepts('html');
// => "html"
ctx.accepts('text/html');
// => "text/html"
ctx.accepts('json', 'text');
// => "json"
ctx.accepts('application/json');
// => "application/json"
// Accept: text/*, application/json
ctx.accepts('image/png');
ctx.accepts('png');
// => false
// Accept: text/*;q=.5, application/json
ctx.accepts(['html', 'json']);
ctx.accepts('html', 'json');
// => "json"
// No Accept header
ctx.accepts('html', 'json');
// => "html"
ctx.accepts('json', 'html');
// => "json"
您可以根据需要多次调用 ctx.accepts(),活着使用switch :
switch (ctx.accepts('json', 'html', 'text')) {
case 'json': break;
case 'html': break;
case 'text': break;
default: ctx.throw(406, 'json, html, or text only');
}
request.acceptsEncodings(encodings)
检查编码是否可接受,为true时返回最佳匹配,否则为false。请注意,您应该将identity作为编码之一!
// Accept-Encoding: gzip
ctx.acceptsEncodings('gzip', 'deflate', 'identity');
// => "gzip"
ctx.acceptsEncodings(['gzip', 'deflate', 'identity']);
// => "gzip"
当没有给出参数时,所有接受的编码都作为数组返回:
// Accept-Encoding: gzip, deflate
ctx.acceptsEncodings();
// => ["gzip", "deflate", "identity"]
请注意,如果客户端显式发送 identity;q=0,则identity编码(这意味着没有编码)可能是不可接受的。
request.acceptsCharsets(charsets)
检查字符集是否可接受,如果为 true,则返回最佳匹配,否则为 false。
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
ctx.acceptsCharsets('utf-8', 'utf-7');
// => "utf-8"
ctx.acceptsCharsets(['utf-7', 'utf-8']);
// => "utf-8"
当没有给出参数时,所有接受的字符集都作为数组返回:
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
ctx.acceptsCharsets();
// => ["utf-8", "utf-7", "iso-8859-1"]
request.acceptsLanguages(langs)
查语言是否可以接受,如果为真则返回最佳匹配,否则为false。
// Accept-Language: en;q=0.8, es, pt
ctx.acceptsLanguages('es', 'en');
// => "es"
ctx.acceptsLanguages(['en', 'es']);
// => "es"
当没有给出参数时,所有接受的语言都作为数组返回:
// Accept-Language: en;q=0.8, es, pt
ctx.acceptsLanguages();
// => ["es", "pt", "en"]
request.idempotent
检查请求是否是幂等的。
request.socket
返回请求套接字。
request.get(field)
返回带有不区分大小写字段的请求标头。
Response
Koa Response对象是节点普通响应对象之上的抽象,提供了对日常 HTTP 服务器开发有用的附加功能。
API
response.header
响应头对象。
response.headers
响应头对象。response.header别名
response.socket
响应套接字。指向 net.Socket 实例作为 request.socket。
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.status 默认设置为 404,因此要发送没有正文和不同状态的响应,如下所示:
ctx.response.status = 200;
// Or whatever other status
ctx.response.status = 204;
response.message
获取响应状态消息。默认情况下,response.message 与 response.status 相关联。
response.message=
将响应状态消息设置为给定值。
response.length
存在时以数字形式返回响应 Content-Length,或者在可能的情况下从 ctx.body 推导出来,或者undefined。
response.length=
将响应内容长度设置为给定值。
response.body
获取响应正文
response.body=
将响应正文设置为以下之一:
- string written
- Buffer written
- Stream piped
- Object || Array json-stringified
- null || undefined no content response
如果没有设置 response.status,Koa 会根据 response.body 自动设置 status 为 200 或 204。具体来说,如果 response.body 没有设置或者已经设置为 null 或 undefined,Koa 会自动设置 response.status 为 204。如果您真的不想发送其他状态的内容响应,您应该通过以下方式覆盖 204 状态:
// This must be always set first before status, since null | undefined
// body automatically sets the status to 204
ctx.body = null;
// Now we override the 204 status with the desired one
ctx.status = 200;
Koa 并没有防范所有可以作为响应体的东西——一个函数没有有意义的序列化,根据您的应用程序返回一个布尔值可能是有意义的,虽然错误有效,但它可能无法像某些预期的那样工作错误的属性不可枚举。
app.use(async (ctx, next) => {
await next()
ctx.assert.equal('object', typeof ctx.body, 500, 'some dev did something wrong')
})
String
Content-Type 默认为 text/html 或 text/plain,两者都具有 utf-8 的默认字符集。Content-Length 字段也被设置。
Buffer
Content-Type 默认为 application/octet-stream,并且 Content-Length 也被设置。
Stream
Content-Type 默认为 application/octet-stream。每当将流设置为响应主体时, .onerror 都会自动添加为错误事件的侦听器以捕获任何错误。此外,只要请求关闭(甚至是过早关闭),流就会被销毁。如果您不想要这两个功能,请不要直接将流设置为主体。例如,在代理中将主体设置为 HTTP 流时,您可能不希望这样做,因为它会破坏底层连接。
有关更多信息,请参阅:github.com/koajs/koa/p…。
这是一个不自动销毁流的流错误处理示例:
const PassThrough = require('stream').PassThrough;
app.use(async ctx => {
ctx.body = someHTTPStream.on('error', (err) => ctx.onerror(err)).pipe(PassThrough());
});
Object
Content-Type 默认为 application/json。这包括普通对象 { foo: 'bar' } 和数组 ['foo', 'bar']。
response.get(field)
获取带有不区分大小写字段的响应标头字段值。
const etag = ctx.response.get('ETag');
response.has(field)
如果由名称标识的标头当前设置在传出标头中,则返回 true。标头名称匹配不区分大小写
const rateLimited = ctx.response.has('X-RateLimit-Limit');
response.set(field, value)
设置响应头字段:
ctx.set('Cache-Control', 'no-cache');
response.append(field, value)
附加带有值 val 的附加标头字段。
ctx.append('Link', '<http://127.0.0.1/>');
response.set(fields)
用一个对象设置几个响应头字段:
ctx.set({
'Etag': '1234',
'Last-Modified': date
});
这委托给 setHeader 通过指定的键设置或更新标头,并且不会重置整个标头。
response.remove(field)
删除响应头字段
response.type
获取响应 Content-Type 参数,例如“charset”。
const ct = ctx.type;
// => "image/png"
response.type=
通过 mime 字符串或文件扩展名设置响应 Content-Type。
ctx.type = 'text/plain; charset=utf-8';
ctx.type = 'image/png';
ctx.type = '.png';
ctx.type = 'png';
注意:当为您选择适当的字符集时,例如 response.type = 'html' 将默认为“utf-8”,如果您需要覆盖字符集,请使用 ctx.set('Content-Type', 'text/html') 直接将响应头字段设置为值。
response.is(types...)
与 ctx.request.is() 非常相似。检查响应类型是否是提供的类型之一。这对于创建操纵响应的中间件特别有用。
例如,这是一个中间件,可以缩小除流之外的所有 HTML 响应。
const minify = require('html-minifier');
app.use(async (ctx, next) => {
await next();
if (!ctx.response.is('html')) return;
let body = ctx.body;
if (!body || body.pipe) return;
if (Buffer.isBuffer(body)) body = body.toString();
ctx.body = minify(body);
});
response.redirect(url, [alt])
执行 [302] 重定向到 url。
当 Referrer 不存在时,字符串“back”是特殊的,以提供 Referrer 支持 alt 或使用“/”。
ctx.redirect('back');
ctx.redirect('back', '/index.html');
ctx.redirect('/login');
ctx.redirect('http://google.com');
要更改 302 的默认状态,只需在此调用之前或之后分配状态。要更改主体,请在此调用之后分配它:
ctx.status = 301;
ctx.redirect('/cart');
ctx.body = 'Redirecting to shopping cart';
response.attachment([filename], [options])
将 Content-Disposition 设置为“附件”以向客户端发出提示下载的信号。可以选择指定下载的文件名和一些选项。
response.headerSent
检查是否已发送响应标头。对于查看客户端是否会收到错误通知很有用。
response.lastModified
将 Last-Modified 标头作为日期返回(如果存在)
response.lastModified=
将 Last-Modified 标头设置为适当的 UTC 字符串。您可以将其设置为日期或日期字符串。
ctx.response.lastModified = new Date();
response.etag=
设置响应的 ETag,包括包装的 's.请注意,没有对应的 response.etag访问属性。
ctx.response.etag = crypto.createHash('md5').update(ctx.body).digest('hex');
response.vary(field)
改变field
response.flushHeaders()
刷新所有设置的标头,然后开始正文。
Links
- GitHub repository
- Examples
- Middleware
- Wiki
- Mailing list
- Guide
- FAQ
- #koajs on freenode