基于 Node.js 平台的下一代 web 开发框架,包含 Koa 的 API 参考列表和一些示例
入门
Hello World
Koa 需要 node v7.6.0 或更高版本来支持ES2015、异步方法,你可以安装自己支持的 node
版本
安装依赖
1 2 3 4 5
| $ mkdir myapp $ cd myapp $ nvm install 7 $ npm init -y $ npm install koa
|
入口文件 index.js
添加代码:
1 2 3 4 5 6 7 8
| const Koa = require('koa'); const app = new Koa();
app.use(async ctx => { ctx.body = 'Hello World'; });
app.listen(3000);
|
使用以下命令运行应用程序
级联
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const Koa = require('koa'); const app = new Koa();
app.use(async (ctx, next) => { const start = Date.now(); await next(); const ms = Date.now() - start; ctx.set('X-Response-Time', `${ms}ms`); });
app.use(async (ctx, next) => { const start = Date.now(); await next(); const ms = Date.now() - start; console.log( `${ctx.method} ${ctx.url} - ${ms}` ); });
app.use(async ctx => { ctx.body = 'Hello World'; }); app.listen(3000);
|
配置
:- |
:- |
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 (表示无穷大) |
app.callback()
:- |
:- |
app.listen(...) # |
为一个绑定 3000 端口的简单 Koa 应用 |
app.callback() # |
返回一个适合 http.createServer() 方法的回调函数用来处理请求 |
app.use(function) # |
添加指定的中间件,详情请看 Middleware |
app.keys # |
设置签名 cookie 密钥 |
app.context # |
从中创建 ctx 的原型 |
错误处理
1 2 3
| app.on('error', (err, ctx) => { log.error('server error', err, ctx) });
|
默认情况下 Koa
会将所有错误信息输出到 stderr
, 除非 app.silent
是 true
。当 err.status
是 404
或者 err.expose
时,默认错误处理程序也不会输出错误
Context 示例
1 2 3 4 5
| app.use(async ctx => { ctx; ctx.request; ctx.response; });
|
app.listen(…)
1 2 3
| const Koa = require('koa'); const app = new Koa(); app.listen(3000);
|
app.listen(...)
实际上是以下代码的语法糖:
1 2 3 4
| const http = require('http'); const Koa = require('koa'); const app = new Koa(); http.createServer(app.callback()).listen(3000);
|
这意味着您可以同时支持 HTTPS
和 HTTPS
,或者在 多个端口
监听同一个应用
1 2 3 4 5 6
| 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);
|
ctx.throw 示例
1 2 3
| ctx.throw(400); ctx.throw(400, 'name required'); ctx.throw(400, 'name required', { user: user });
|
this.throw('name required', 400)
等价于
1 2 3 4
| const err = new Error('name required'); err.status = 400; err.expose = true; throw err;
|
ctx.assert 示例
1 2 3 4 5
| ctx.assert( ctx.state.user, 401, 'User not found. Please login!' );
|
Context(上下文) API
:- |
:- |
ctx.req |
Node 的 request 对象 |
ctx.res |
Node 的 response 对象 |
ctx.request |
Koa 的 Request 对象 |
ctx.response |
Koa 的 Response 对象 |
ctx.state |
推荐的命名空间,用于通过中间件传递信息到前端视图 |
ctx.app |
应用实例引用 |
ctx.app.emit |
发出由第一个参数定义的类型的事件 |
ctx.cookies.get(name, [options]) |
获得 cookie 中名为 name 的值 |
ctx.cookies.set(name, value, [options]) |
设置 cookie 中名为 name 的值 |
ctx.throw([status], [msg], [properties]) |
抛出包含 .status 属性的错误,默认为 500 |
ctx.assert(value, [status], [msg], [properties]) |
当 !value 时, Helper 方法抛出一个类似 .throw() 的错误 |
ctx.respond |
避免使用 Koa 的内置响应处理功能,您可以直接赋值 this.repond = false |
ctx.cookies.set 参数
:- |
:- |
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(映射为“strect”) |
signed |
一个布尔值,指示是否对cookie进行签名(默认为false)。如果这是真的,还将发送另一个附加了.sig后缀的同名cookie,其中一个27字节的url安全base64 SHA1值表示cookie name=cookie值相对于第一个Keygrip键的哈希值。此签名密钥用于在下次收到cookie时检测篡改 |
overwrite |
一个布尔值,指示是否覆盖以前设置的同名 cookie (默认为false)。如果为true,则在设置此Cookie时,将从set-Cookie标头中筛选出在同一请求期间设置的具有相同名称的所有Cookie(无论路径或域如何) |
请求(Request)
:- |
:- |
request.header |
请求头对象 |
request.header= |
设置请求头对象 |
request.headers |
请求头对象。等价于 request.header. |
request.headers= |
设置请求头对象。 等价于request.header=. |
request.method |
请求方法 |
request.method= |
设置请求方法, 在实现中间件时非常有用,比如 methodOverride() |
request.length |
以数字的形式返回 request 的内容长度(Content-Length),或者返回 undefined。 |
request.url |
获得请求url地址. |
request.url= |
设置请求地址,用于重写url地址时 |
request.originalUrl |
获取请求原始地址 |
request.origin |
获取URL原始地址, 包含 protocol 和 host |
request.href |
获取完整的请求URL, 包含 protocol, host 和 url |
request.path |
获取请求路径名 |
request.path= |
设置请求路径名并保留当前查询字符串 |
request.querystring |
获取查询参数字符串(url中?后面的部分),不包含? |
request.querystring= |
设置原始查询字符串 |
request.search |
获取查询参数字符串,包含? |
request.search= |
设置原始查询字符串 |
request.host |
获取 host (hostname:port)。 当 app.proxy 设置为 true 时,支持 X-Forwarded-Host |
request.hostname |
获取 hostname。当 app.proxy 设置为 true 时,支持 X-Forwarded-Host。 |
request.URL |
获取 WHATWG 解析的对象. |
request.type |
获取请求 Content-Type,不包含像 “charset” 这样的参数。 |
request.charset |
获取请求 charset,没有则返回 undefined |
request.query |
将查询参数字符串进行解析并以对象的形式返回,如果没有查询参数字字符串则返回一个空对象 |
request.query= |
根据给定的对象设置查询参数字符串 |
request.fresh |
检查请求缓存是否 “fresh”(内容没有发生变化) |
request.stale |
与 req.fresh 相反 |
request.protocol |
返回请求协议,”https” 或者 “http” |
request.secure |
简化版 this.protocol == “https”,用来检查请求是否通过 TLS 发送 |
request.ip |
请求远程地址,当 app.proxy 设置为 true 时,支持 X-Forwarded-Host |
request.ips |
当 X-Forwarded-For 存在并且 app.proxy 有效,将会返回一个有序(从 upstream 到 downstream)ip 数组 |
request.subdomains |
以数组形式返回子域名 |
request.is(types...) |
检查请求所包含的 “Content-Type” 是否为给定的 type 值 |
request.accepts(types) |
检查给定的类型 types(s) 是否可被接受,当为 true 时返回最佳匹配,否则返回 false |
request.acceptsEncodings(encodings) |
检查 encodings 是否可以被接受,当为 true 时返回最佳匹配,否则返回 false |
request.acceptsCharsets(charsets) |
检查 charsets 是否可以被接受,如果为 true 则返回最佳匹配,否则返回 false |
request.acceptsLanguages(langs) |
检查 langs 是否可以被接受,如果为 true 则返回最佳匹配,否则返回 false |
request.idempotent |
检查请求是否为幂等(idempotent) |
request.socket |
返回请求的socket |
request.get(field) |
返回请求头 |
响应(Response)
:- |
:- |
response.header |
Response header 对象 |
response.headers |
Response header 对象。等价于 response.header. |
response.socket |
Request socket. |
response.status |
获取响应状态。 默认情况下,response.status设置为404,而不像node’s res.statusCode默认为200。 |
response.status= |
通过数字设置响应状态 |
response.message |
获取响应状态消息。默认情况下, response.message关联response.status。 |
response.message= |
将响应状态消息设置为给定值。 |
response.length= |
将响应Content-Length设置为给定值。 |
response.length |
如果 Content-Length 作为数值存在,或者可以通过 ctx.body 来进行计算,则返回相应数值,否则返回 undefined。 |
response.body |
获取响应体。 |
response.body= |
设置响应体为如 string ,Buffer ,Stream ,Object|Array ,null |
response.get(field) |
获取 response header 中字段值,field 不区分大小写 |
response.set(field, value) |
设置 response header 字段 field 的值为 value |
response.append(field, value) |
添加额外的字段field 的值为 val |
response.set(fields) |
使用对象同时设置 response header 中多个字段的值 |
response.remove(field) |
移除 response header 中字段 filed |
response.type |
获取 response Content-Type,不包含像”charset”这样的参数 |
response.type= |
通过 mime 类型的字符串或者文件扩展名设置 response Content-Type |
response.is(types...) |
跟 ctx.request.is() 非常类似。用来检查响应类型是否是所提供的类型之一 |
response.redirect(url, [alt]) |
执行 [302] 重定向到对应 url |
response.attachment([filename]) |
设置 “attachment” 的 Content-Disposition,用于给客户端发送信号来提示下载 |
response.headerSent |
检查 response header 是否已经发送,用于在发生错误时检查客户端是否被通知。 |
response.lastModified |
如果存在 Last-Modified,则以 Date 的形式返回。 |
response.lastModified= |
以 UTC 格式设置 Last-Modified。您可以使用 Date 或 date 字符串来进行设置。 |
response.etag= |
设置 包含 “s 的 ETag |
response.vary(field) |
不同于field. |
response.flushHeaders() |
刷新任何设置的响应头,并开始响应体 |
请求(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()
响应(Response)别名
以下访问器和别名与 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.fresh 示例
1 2 3 4 5 6 7 8 9 10 11 12 13
| ctx.status = 200; ctx.set('ETag', '123');
if (ctx.fresh) { ctx.status = 304; return; }
ctx.body = await db.find('something');
|
ctx.is 示例
1 2 3 4 5 6 7 8 9 10 11 12 13
| ctx.is('html'); ctx.is('text/html'); ctx.is('text/*', 'text/html');
ctx.is('json', 'urlencoded'); ctx.is('application/json');
ctx.is('html', 'application/*');
ctx.is('html');
|
ctx.accepts 示例
1 2 3 4 5 6 7 8 9
| ctx.accepts('html');
ctx.accepts('text/html');
ctx.accepts('json', 'text');
ctx.accepts('application/json');
|
request.acceptsCharsets 示例
1 2 3 4 5 6
| ctx.acceptsCharsets('utf-8', 'utf-7');
ctx.acceptsCharsets(['utf-7', 'utf-8']);
|
检查 charsets
是否可以被接受,如果为 true
则返回最佳匹配, 否则返回 false
response.set 示例
1 2 3 4
| ctx.set({ 'Etag': '1234', 'Last-Modified': date });
|
使用对象同时设置 response header 中多个字段的值
response.type 示例
获取 response Content-Type,不包含像”charset”这样的参数