app.listen(...)
Koa 應用並非是一個 1-to-1 表征關系的 HTTP 服務器。 一個或多個Koa應用可以被掛載到一起組成一個包含單一 HTTP 服務器的大型應用群。
var koa = require('koa'); var app = koa(); app.listen(3000);
app.listen(...)
實際上是以下代碼的語法糖:
var http = require('http'); var koa = require('koa'); var app = koa(); http.createServer(app.callback()).listen(3000);
這意味着您可以同時支持 HTTP 和 HTTPS,或者在多個端口監聽同一個應用。
const http = require('http'); const Koa = require('koa'); const app = new Koa(); http.createServer(app.callback()).listen(3000); http.createServer(app.callback()).listen(3001);
app.callback()
返回一個適合 http.createServer()
方法的回調函數用來處理請求。 您也可以使用這個回調函數將您的app掛載在 Connect/Express 應用上。
/** * Create HTTP server. */ var server = http.createServer(app.callback()); /** * Listen on provided port, on all network interfaces. */ server.listen(port); server.on('error', onError); server.on('listening', onListening);
app.use(function)
為應用添加指定的中間件,詳情請看 Middleware
app.keys=
設置簽名Cookie密鑰,該密鑰會被傳遞給 KeyGrip。
當然,您也可以自己生成 KeyGrip
實例:
app.keys = ['im a newer secret', 'i like turtle']; app.keys = new KeyGrip(['im a newer secret', 'i like turtle'], 'sha256');
在進行cookie簽名時,只有設置 signed
為 true
的時候,才會使用密鑰進行加密:
ctx.cookies.set('name', 'tobi', { signed: true });
app.context
app.context 是ctx中創造來的,你可以對通過app.context ctx增加屬性。這是一個很有用的屬性用來貫穿你的整個app.app.context
is the prototype from which ctx
is created from. You may add additional properties to ctx
by editing app.context
. This is useful for adding properties or methods to ctx
to be used across your entire app, which may be more performant (no middleware) and/or easier (fewer require()
s) at the expense of relying more on ctx
, which could be considered an anti-pattern.
app.context.db = db(); app.use(async (ctx) => { console.log(ctx.db); });
錯誤處理
默認情況下Koa會將所有錯誤信息輸出到 stderr,除非 NODE_ENV 是 "test"。為了實現自定義錯誤處理邏輯(比如 centralized logging),您可以添加 "error" 事件監聽器。
app.on('error', function(err){ log.error('server error', err); });
如果錯誤發生在 請求/響應 環節,並且其不能夠響應客戶端時,Contenxt
實例也會被傳遞到 error
事件監聽器的回調函數里。
app.on('error', function(err, ctx){ log.error('server error', err, ctx); });
當發生錯誤但仍能夠響應客戶端時(比如沒有數據寫到socket中),Koa會返回一個500錯誤(Internal Server Error)。
無論哪種情況,Koa都會生成一個應用級別的錯誤信息,以便實現日志記錄等目的。
Context(上下文)
Koa Context 將 node 的 request
和 response
對象封裝在一個單獨的對象里面,其為編寫 web 應用和 API 提供了很多有用的方法。
這些操作在 HTTP 服務器開發中經常使用,因此其被添加在上下文這一層,而不是更高層框架中,因此將迫使中間件需要重新實現這些常用方法。
context
在每個 request 請求中被創建,在中間件中作為接收器(receiver)來引用.
在KOA1.0中
app.use(function *(){ this; // is the Context this.request; // is a koa Request this.response; // is a koa Response });
在KOA2.0中
app.use(async (ctx, next) => { ctx; // is the Context ctx.request; // is a koa Request ctx.response; // is a koa Response });
API
Context
詳細的方法和訪問器。
ctx.req
Node 的 request
對象。
ctx.res
Koa 不支持 直接調用底層 res 進行響應處理。請避免使用以下 node 屬性:
res.statusCode,res.writeHead(),res.write(),res.end()
ctx.request
Koa 的 Request
對象。
ctx.response
Koa 的 Response
對象。
ctx.app
應用實例引用。
ctx.cookies.get(name, [options])
獲得 cookie 中名為 name
的值,options
為可選參數:
- 'signed': 如果為 true,表示請求時 cookie 需要進行簽名。
注意:Koa 使用了 Express 的 cookies 模塊,options 參數只是簡單地直接進行傳遞。
ctx.cookies.set(name, value, [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 參數只是簡單地直接進行傳遞。
if ( req.url == "/set" ) { cookies // set a regular cookie .set( "unsigned", "foo", { httpOnly: false } ) // set a signed cookie .set( "signed", "bar", { signed: true } ) // mimic a signed cookie, but with a bogus signature .set( "tampered", "baz" ) .set( "tampered.sig", "bogus" ) res.writeHead( 302, { "Location": "/" } ) return res.end( "Now let's check." ) }
ctx.throw(msg, [status])
拋出包含 .status
屬性的錯誤,默認為 500
。該方法可以讓 Koa 准確的響應處理狀態。 Koa支持以下組合:
ctx.throw(403);
ctx.throw('name required', 400);
ctx.throw(400, 'name required');
ctx.throw('something exploded');
ctx.respond
為了避免使用 Koa 的內置響應處理功能,您可以直接賦值 this.repond = false;
。如果您不想讓 Koa 來幫助您處理 reponse,而是直接操作原生 res
對象,那么請使用這種方法。
注意: 這種方式是不被 Koa 支持的。其可能會破壞 Koa 中間件和 Koa 本身的一些功能。其只作為一種 hack 的方式,並只對那些想要在 Koa 方法和中間件中使用傳統 fn(req, res)
方法的人來說會帶來便利。
Request aliases
以下訪問器和別名與 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 aliases
以下訪問器和別名與 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=