1.前言
这篇我们一起来学习 Context ,Request,Response,这 3 个最常用的 Api。
2.上下文(Context)
Koa Context 将 node 的 request 和 response 对象封装到单个对象中,为编写 Web 应用程序和 API 提供了许多有用的方法。通过这种上下文的方式,使用起来比较方便, 这些操作在 HTTP 服务器开发中频繁使用,它们被添加到此级别而不是更高级别的框架,这将强制中间件重新实现此通用功能。
每个 请求都将创建一个 Context,并在中间件中作为接收器引用,或者 ctx 标识符,如以下代码片段所示:
app.use(async ctx => {ctx; // 这是 Contextctx.request; // 这是 koa Requestctx.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.statusCoderes.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() 得到的毫秒数signedcookie 签名值expirescookie 过期的Datepathcookie 路径, 默认是'/'domaincookie 域名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.headerctx.headersctx.methodctx.method=ctx.urlctx.url=ctx.originalUrlctx.originctx.hrefctx.pathctx.path=ctx.queryctx.query=ctx.querystringctx.querystring=ctx.hostctx.hostnamectx.freshctx.stalectx.socketctx.protocolctx.securectx.ipctx.ipsctx.subdomainsctx.is()ctx.accepts()ctx.acceptsEncodings()ctx.acceptsCharsets()ctx.acceptsLanguages()-
4. Response 别名
以下访问器和 Response别名等效:
ctx.bodyctx.body=ctx.statusctx.status=ctx.messagectx.message=ctx.length=ctx.lengthctx.type=ctx.typectx.headerSentctx.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) // GETconsole.log(request.url) // /user/detail/1?name=3434console.log(request.originalUrl) // /user/detail/1?name=3434console.log(request.href) // /user/detail/1?name=3434console.log(request.path) // /user/detail/1console.log(request.querystring) // name=3434console.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||ArrayJSON-字符串化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。
