1.前言
这篇我们一起来学习 Context ,Request,Response,这 3 个最常用的 Api。
2.上下文(Context)
Koa Context 将 node 的 request
和 response
对象封装到单个对象中,为编写 Web 应用程序和 API 提供了许多有用的方法。通过这种上下文的方式,使用起来比较方便, 这些操作在 HTTP 服务器开发中频繁使用,它们被添加到此级别而不是更高级别的框架,这将强制中间件重新实现此通用功能。
每个 请求都将创建一个 Context
,并在中间件中作为接收器引用,或者 ctx
标识符,如以下代码片段所示:
app.use(async ctx => {
ctx; // 这是 Context
ctx.request; // 这是 koa Request
ctx.response; // 这是 koa Response
});
为方便起见许多上下文的访问器和方法直接委托给它们的 ctx.request
或 ctx.response
,不然的话它们是相同的。 例如 ctx.type
和 ctx.length
委托给 response
对象,ctx.path
和 ctx.method
委托给 request
。
2.1 ctx.req
2.2 ctx.res
Node 的 response
对象。
绕过 Koa 的 response 处理是 不被支持的. 应避免使用以下 node 属性:
res.statusCode
res.writeHead()
res.write()
-
在使用过程中,我们应该尽量避免使用ctx.req,ctx.res,这这个对象是绕过了 Koa 来处理 Http请求的 request 和 response,会出现一些意想不到的问题。
2.3 ctx.request
2.4 ctx.response
2.5 ctx.app
2.6 ctx.cookies.get(name, [options])
通过
options
获取 cookiename
: signed
所请求的cookie应该被签名
koa 使用 cookies模块,其中只需传递参数。
2.7 ctx.cookies.set(name, value, [options])
通过 options
设置 cookie name
的 value
:
maxAge
一个数字表示从 Date.now() 得到的毫秒数signed
cookie 签名值expires
cookie 过期的Date
path
cookie 路径, 默认是'/'
domain
cookie 域名secure
安全 cookiehttpOnly
服务器可访问 cookie, 默认是 trueoverwrite
一个布尔值,表示是否覆盖以前设置的同名的 cookie (默认是 false). 如果是 true, 在同一个请求中设置相同名称的所有 Cookie(不管路径或域)是否在设置此Cookie 时从 Set-Cookie 标头中过滤掉。
koa 使用传递简单参数的 cookies 模块。
2.8 ctx.throw([status], [msg], [properties])
Helper 方法抛出一个 .status
属性默认为 500
的错误,这将允许 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;
2.9 ctx.respond
为了绕过 Koa 的内置 response 处理,你可以显式设置 ctx.respond = false;
。 如果您想要写入原始的 res
对象而不是让 Koa 处理你的 response,请使用此参数。
请注意,Koa 不 支持使用此功能。这可能会破坏 Koa 中间件和 Koa 本身的预期功能。使用这个属性被认为是一个 hack,只是便于那些希望在 Koa 中使用传统的 fn(req, res)
功能和中间件的人。
3 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()
-
4. 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=
5. 请求(Request)
KoaRequest
对象是在 node 的 vanilla 请求对象之上的抽象,提供了诸多对 HTTP 服务器开发有用的功能。5.1 列举几个工作中常用的 api
假设我们现在有个 get请求 http://localhost:3000/user/detail/1?name=3434,下面代码打印了我们常用的几个属性,更多可以看官方api。
function detail(ctx) {
const id = ctx.params.id;
const { request, response } = ctx;
console.log(request.headers)
console.log(request.query) // { name: '3434' }
console.log(request.method) // GET
console.log(request.url) // /user/detail/1?name=3434
console.log(request.originalUrl) // /user/detail/1?name=3434
console.log(request.href) // /user/detail/1?name=3434
console.log(request.path) // /user/detail/1
console.log(request.querystring) // name=3434
console.log(request.type)
ctx.body = {
data: array[id],
success: true
}
}
module.exports = {
detail,
list
}
5.1.1 request.header
请求标头对象,使用 request.headers
也是可以的。
5.1.2 request.query
获取解析的查询字符串, 当没有查询字符串时,返回一个空对象。请注意,此 getter 不 支持嵌套解析。
例如 “color=blue&size=small”:
{
color: 'blue',
size: 'small'
}
5.1.3 request.method
5.1.4 request.url
5.1.5 request.originalUrl
5.1.6 request.href
获取完整的请求URL,包括 protocol
,host
和 url
ctx.request.href;
// => http://example.com/foo/bar?q=1
5.1.7 request.path
5.1.8 request.path=
5.1.9 request.querystring
5.1.10 request.querystring=
5.1.11 request.search
5.2 request.type
获取请求 Content-Type
不含参数 “charset”。
const ct = ctx.request.type;
// => "image/png"
6. 响应(Response)
Koa Response
对象是在 node 的 vanilla 响应对象之上的抽象,提供了诸多对 HTTP 服务器开发有用的功能。
const array = [{id: 0, name: '王二'}, {id: 1, name: '赵三'}]
function detail(ctx) {
ctx.response.body = {
data: array[id],
success: true
}
ctx.response.set("hc-test", 1)
ctx.response.status = 200
}
// 或者通过 上面 ctx Response 别名
function detail(ctx) {
ctx.body = {
data: array[id],
success: true
}
ctx.status = 200
}
6.1 常用API
6.1.1 response.headers
6.1.2 response.status
6.1.3 response.status=
通过数字代码设置响应状态,常见的如 200,404, 301, 302。如果 response.status
未被设置, Koa 将会自动设置状态为 200
或 204
。
6.1.4 response.body
6.1.5 response.body=
将响应体设置为以下之一:
string
写入Buffer
写入Stream
管道Object
||Array
JSON-字符串化null
无内容响应6.1.6 String
Content-Type 默认为text/html
或text/plain
, 同时默认字符集是 utf-8。Content-Length 字段也是如此。6.1.7 Object
Content-Type 默认为application/json
. 这包括普通的对象{ foo: 'bar' }
和数组['foo', 'bar']
。6.1.8 Buffer
Content-Type 默认为application/octet-stream
, 并且 Content-Length 字段也是如此。6.1.9 Stream
Content-Type 默认为application/octet-stream
。
每当流被设置为响应主体时,.onerror
作为侦听器自动添加到error
事件中以捕获任何错误。此外,每当请求关闭(甚至过早)时,流都将被销毁。如果你不想要这两个功能,请勿直接将流设为主体。例如,当将主体设置为代理中的 HTTP 流时,你可能不想要这样做,因为它会破坏底层连接。
以下是流错误处理的示例,而不会自动破坏流:const PassThrough = require('stream').PassThrough;
app.use(async ctx => {
ctx.body = someHTTPStream.on('error', ctx.onerror).pipe(PassThrough());
});
6.1.10 response.set(field, value)
设置响应标头field
到value
:ctx.set('Cache-Control', 'no-cache');
6.1.11 response.set(fields)
用一个对象设置多个响应标头fields
:ctx.set({
'Etag': '1234',
'Last-Modified': date
});
6.1.12 response.remove(field)
删除标头field
。6.1.13 response.redirect(url, [alt])
执行 [302] 重定向到url
.
字符串 “back” 是特别提供Referrer支持的,当Referrer不存在时,使用alt
或“/”。
要更改 “302” 的默认状态,只需在该调用之前或之后分配状态。要变更主体请在此调用之后:ctx.redirect('back');
ctx.redirect('back', '/index.html');
ctx.redirect('/login');
ctx.redirect('http://google.com');
ctx.status = 301;
ctx.redirect('/cart');
ctx.body = 'Redirecting to shopping cart';
7 小结
这节我们总结了 上下文 Context, Request,Response 的基本使用,这3 个对象在平常使用中最频繁,大家要好好掌握,因为 这个3个对象下挂载了非常多的属性,方法,平常使用过程中,不知道了可以查查官方文档,对应代码 koa-context。