Koa Context 將 node 的 request
和 response
對象封裝在一個單獨的對象裏面,其爲編寫 web 應用和 API 提供了不少有用的方法。css
這些操做在 HTTP 服務器開發中常用,所以其被添加在上下文這一層,而不是更高層框架中,所以將迫使中間件須要從新實現這些經常使用方法。html
context
在每一個 request 請求中被建立,在中間件中做爲接收器(receiver)來引用,或者經過 this
標識符來引用:node
app.use(function *(){ this; // is the Context this.request; // is a koa Request this.response; // is a koa Response });
許多 context 的訪問器和方法爲了便於訪問和調用,簡單的委託給他們的 ctx.request
和ctx.response
所對應的等價方法, 好比說 ctx.type
和 ctx.length
代理了 response
對象中對應的方法,ctx.path
和 ctx.method
代理了 request
對象中對應的方法。git
Context
詳細的方法和訪問器。github
Node 的 request
對象。web
Node 的 response
對象。express
Koa 不支持 直接調用底層 res 進行響應處理。請避免使用如下 node 屬性:json
res.statusCode
數組
res.writeHead()
緩存
res.write()
res.end()
Koa 的 Request
對象。
Koa 的 Response
對象。
應用實例引用。
得到 cookie 中名爲 name
的值,options
爲可選參數:
'signed': 若是爲 true,表示請求時 cookie 須要進行簽名。
注意:Koa 使用了 Express 的 cookies 模塊,options 參數只是簡單地直接進行傳遞。
設置 cookie 中名爲 name
的值,options
爲可選參數:
signed
: 是否要作簽名
expires
: cookie 有效期時間
path
: cookie 的路徑,默認爲 /'
domain
: cookie 的域
secure
: false 表示 cookie 經過 HTTP 協議發送,true 表示 cookie 經過 HTTPS 發送。
httpOnly
: true 表示 cookie 只能經過 HTTP 協議發送
注意:Koa 使用了 Express 的 cookies 模塊,options 參數只是簡單地直接進行傳遞。
拋出包含 .status
屬性的錯誤,默認爲 500
。該方法可讓 Koa 準確的響應處理狀態。 Koa支持如下組合:
this.throw(403) this.throw('name required', 400) this.throw(400, 'name required') this.throw('something exploded')
this.throw('name required', 400)
等價於:
var err = new Error('name required'); err.status = 400; throw err;
注意:這些用戶級錯誤被標記爲 err.expose
,其意味着這些消息被準確描述爲對客戶端的響應,而並不是使用在您不想泄露失敗細節的場景中。
爲了不使用 Koa 的內置響應處理功能,您能夠直接賦值 this.repond = false;
。若是您不想讓 Koa 來幫助您處理 reponse,而是直接操做原生 res
對象,那麼請使用這種方法。
注意: 這種方式是不被 Koa 支持的。其可能會破壞 Koa 中間件和 Koa 自己的一些功能。其只做爲一種 hack 的方式,並只對那些想要在 Koa 方法和中間件中使用傳統 fn(req, res)
方法的人來講會帶來便利。
如下訪問器和別名與 Request 等價:
ctx.header
ctx.method
ctx.method=
ctx.url
ctx.url=
ctx.originalUrl
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.length=
ctx.length
ctx.type=
ctx.type
ctx.headerSent
ctx.redirect()
ctx.attachment()
ctx.set()
ctx.remove()
ctx.lastModified=
ctx.etag=
Koa Request
對象是對 node 的 request 進一步抽象和封裝,提供了平常 HTTP 服務器開發中一些有用的功能。
請求頭對象
請求方法
設置請求方法,在實現中間件時很是有用,好比 methodOverride()
。
以數字的形式返回 request 的內容長度(Content-Length),或者返回 undefined
。
得到請求url地址。
設置請求地址,用於重寫url地址時。
獲取請求原始地址。
獲取請求路徑名。
設置請求路徑名,並保留請求參數(就是url中?後面的部分)。
獲取查詢參數字符串(url中?後面的部分),不包含 ?。
設置查詢參數。
獲取查詢參數字符串,包含 ?。
設置查詢參數字符串。
獲取 host (hostname:port)。 當 app.proxy
設置爲 true 時,支持 X-Forwarded-Host
。
獲取 hostname。當 app.proxy
設置爲 true 時,支持 X-Forwarded-Host
。
獲取請求 Content-Type
,不包含像 "charset" 這樣的參數。
var ct = this.request.type; // => "image/png"
獲取請求 charset,沒有則返回 undefined
:
this.request.charset // => "utf-8"
將查詢參數字符串進行解析並以對象的形式返回,若是沒有查詢參數字字符串則返回一個空對象。
注意:該方法不支持嵌套解析。
好比 "color=blue&size=small":
{ color: 'blue', size: 'small' }
根據給定的對象設置查詢參數字符串。
注意:該方法不支持嵌套對象。
this.query = { next: '/login' };
檢查請求緩存是否 "fresh"(內容沒有發生變化)。該方法用於在 If-None-Match
/ ETag
, If-Modified-Since
和 Last-Modified
中進行緩存協調。當在 response headers 中設置一個或多個上述參數後,該方法應該被使用。
this.set('ETag', '123'); // cache is ok if (this.fresh) { this.status = 304; return; } // cache is stale // fetch new data this.body = yield db.find('something');
與 req.fresh
相反。
返回請求協議,"https" 或者 "http"。 當 app.proxy
設置爲 true 時,支持 X-Forwarded-Host
。
簡化版 this.protocol == "https"
,用來檢查請求是否經過 TLS 發送。
請求遠程地址。 當 app.proxy
設置爲 true 時,支持 X-Forwarded-Host
。
當 X-Forwarded-For
存在而且 app.proxy
有效,將會返回一個有序(從 upstream 到 downstream)ip 數組。 不然返回一個空數組。
以數組形式返回子域名。
子域名是在host中逗號分隔的主域名前面的部分。默認狀況下,應用的域名假設爲host中最後兩部分。其可經過設置 app.subdomainOffset
進行更改。
舉例來講,若是域名是 "tobi.ferrets.example.com":
若是沒有設置 app.subdomainOffset
,其 subdomains 爲 ["ferrets", "tobi"]
。 若是設置app.subdomainOffset
爲3,其 subdomains 爲 ["tobi"]
。
檢查請求所包含的 "Content-Type" 是否爲給定的 type 值。 若是沒有 request body,返回undefined
。 若是沒有 content type,或者匹配失敗,返回 false
。 不然返回匹配的 content-type。
// With Content-Type: text/html; charset=utf-8 this.is('html'); // => 'html' this.is('text/html'); // => 'text/html' this.is('text/*', 'text/html'); // => 'text/html' // When Content-Type is application/json this.is('json', 'urlencoded'); // => 'json' this.is('application/json'); // => 'application/json' this.is('html', 'application/*'); // => 'application/json' this.is('html'); // => false
好比說您但願保證只有圖片發送給指定路由:
if (this.is('image/*')) { // process } else { this.throw(415, 'images only!'); }
Koa request
對象包含 content negotiation 功能(由 accepts 和 negotiator 提供):
req.accepts(types)
req.acceptsEncodings(types)
req.acceptsCharsets(charsets)
req.acceptsLanguages(langs)
若是沒有提供 types,將會返回全部的可接受類型。
若是提供多種 types,將會返回最佳匹配類型。若是沒有匹配上,則返回 false
,您應該給客戶端返回 406 "Not Acceptable"
。
爲了防止缺乏 accept headers 而致使能夠接受任意類型,將會返回第一種類型。所以,您提供的類型順序很是重要。
檢查給定的類型 types(s)
是否可被接受,當爲 true 時返回最佳匹配,不然返回 false
。type
的值能夠是一個或者多個 mime 類型字符串。 好比 "application/json" 擴展名爲 "json",或者數組["json", "html", "text/plain"]
。
// Accept: text/html this.accepts('html'); // => "html" // Accept: text/*, application/json this.accepts('html'); // => "html" this.accepts('text/html'); // => "text/html" this.accepts('json', 'text'); // => "json" this.accepts('application/json'); // => "application/json" // Accept: text/*, application/json this.accepts('image/png'); this.accepts('png'); // => false // Accept: text/*;q=.5, application/json this.accepts(['html', 'json']); this.accepts('html', 'json'); // => "json" // No Accept header this.accepts('html', 'json'); // => "html" this.accepts('json', 'html'); // => "json"
this.accepts()
能夠被調用屢次,或者使用 switch:
switch (this.accepts('json', 'html', 'text')) { case 'json': break; case 'html': break; case 'text': break; default: this.throw(406, 'json, html, or text only'); }
檢查 encodings
是否能夠被接受,當爲 true
時返回最佳匹配,不然返回 false
。 注意:您應該在 encodings 中包含 identity
。
// Accept-Encoding: gzip this.acceptsEncodings('gzip', 'deflate', 'identity'); // => "gzip" this.acceptsEncodings(['gzip', 'deflate', 'identity']); // => "gzip"
當沒有傳遞參數時,返回包含全部可接受的 encodings 的數組:
// Accept-Encoding: gzip, deflate this.acceptsEncodings(); // => ["gzip", "deflate", "identity"]
注意:若是客戶端直接發送 identity;q=0
時,identity
encoding(表示no encoding) 能夠不被接受。雖然這是一個邊界狀況,您仍然應該處理這種狀況。
檢查 charsets
是否能夠被接受,若是爲 true
則返回最佳匹配, 不然返回 false
。
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5 this.acceptsCharsets('utf-8', 'utf-7'); // => "utf-8" this.acceptsCharsets(['utf-7', 'utf-8']); // => "utf-8"
當沒有傳遞參數時, 返回包含全部可接受的 charsets 的數組:
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5 this.acceptsCharsets(); // => ["utf-8", "utf-7", "iso-8859-1"]
檢查 langs
是否能夠被接受,若是爲 true
則返回最佳匹配,不然返回 false
。
// Accept-Language: en;q=0.8, es, pt this.acceptsLanguages('es', 'en'); // => "es" this.acceptsLanguages(['en', 'es']); // => "es"
當沒有傳遞參數時,返回包含全部可接受的 langs 的數組:
// Accept-Language: en;q=0.8, es, pt this.acceptsLanguages(); // => ["es", "pt", "en"]
檢查請求是否爲冪等(idempotent)。
返回請求的socket。
返回請求 header 中對應 field 的值。
Koa Response
對象是對 node 的 response 進一步抽象和封裝,提供了平常 HTTP 服務器開發中一些有用的功能。
Response header 對象。
Request socket。
獲取 response status。不一樣於 node 在默認狀況下 res.statusCode
爲200,res.status
並無賦值。
Response status 字符串。
經過 數字狀態碼或者不區分大小寫的字符串來設置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"
300 "multiple choices"
301 "moved permanently"
302 "moved temporarily"
303 "see other"
304 "not modified"
305 "use proxy"
307 "temporary 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 time-out"
409 "conflict"
410 "gone"
411 "length required"
412 "precondition failed"
413 "request entity too large"
414 "request-uri too large"
415 "unsupported media type"
416 "requested range not satisfiable"
417 "expectation failed"
418 "i'm a teapot"
422 "unprocessable entity"
423 "locked"
424 "failed dependency"
425 "unordered collection"
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 time-out"
505 "http version not supported"
506 "variant also negotiates"
507 "insufficient storage"
509 "bandwidth limit exceeded"
510 "not extended"
511 "network authentication required"
注意:不用擔憂記不住這些字符串,若是您設置錯誤,會有異常拋出,並列出該狀態碼錶來幫助您進行更正。
經過給定值設置 response Content-Length。
若是 Content-Length 做爲數值存在,或者能夠經過 res.body
來進行計算,則返回相應數值,不然返回 undefined
。
得到 response body。
設置 response body 爲以下值:
string
written
Buffer
written
Stream
piped
Object
json-stringified
null
no content response
若是 res.status
沒有賦值,Koa會自動設置爲 200
或 204
。
Content-Type 默認爲 text/html 或者 text/plain,兩種默認 charset 均爲 utf-8。 Content-Length 同時會被設置。
Content-Type 默認爲 application/octet-stream,Content-Length同時被設置。
Content-Type 默認爲 application/octet-stream。
Content-Type 默認爲 application/json。
獲取 response header 中字段值,field 不區分大小寫。
var etag = this.get('ETag');
設置 response header 字段 field
的值爲 value
。
this.set('Cache-Control', 'no-cache');
使用對象同時設置 response header 中多個字段的值。
this.set({ 'Etag': '1234', 'Last-Modified': date });
移除 response header 中字段 filed
。
獲取 response Content-Type
,不包含像 "charset" 這樣的參數。
var ct = this.type; // => "image/png"
經過 mime 類型的字符串或者文件擴展名設置 response Content-Type
this.type = 'text/plain; charset=utf-8'; this.type = 'image/png'; this.type = '.png'; this.type = 'png';
注意:當能夠根據 res.type
肯定一個合適的 charset
時,charset
會自動被賦值。 好比 res.type = 'html'
時,charset 將會默認設置爲 "utf-8"。然而當完整定義爲 res.type = 'text/html'
時,charset 不會自動設置。
執行 [302] 重定向到對應 url
。
字符串 "back" 是一個特殊參數,其提供了 Referrer 支持。當沒有Referrer時,使用 alt
或者 /
代替。
this.redirect('back'); this.redirect('back', '/index.html'); this.redirect('/login'); this.redirect('http://google.com');
若是想要修改默認的 [302] 狀態,直接在重定向以前或者以後執行便可。若是要修改 body,須要在重定向以前執行。
this.status = 301; this.redirect('/cart'); this.body = 'Redirecting to shopping cart';
設置 "attachment" 的 Content-Disposition
,用於給客戶端發送信號來提示下載。filename 爲可選參數,用於指定下載文件名。
檢查 response header 是否已經發送,用於在發生錯誤時檢查客戶端是否被通知。
若是存在 Last-Modified
,則以 Date
的形式返回。
以 UTC 格式設置 Last-Modified
。您可使用 Date
或 date 字符串來進行設置。
this.response.lastModified = new Date();
設置 包含 "
s 的 ETag。注意沒有對應的 res.etag
來獲取其值。
this.response.etag = crypto.createHash('md5').update(this.body).digest('hex');
在 header 的 field
後面 追加 val
。
至關於執行res.append('Vary', field)。