koa简介
資料來源:
http://javascript.ruanyifeng.com/nodejs/koa.html
http://koa.bootcss.com/
以下內(nèi)容為摘抄,純屬做筆記加深印象。勿噴。
?
使用 koa 編寫 web 應(yīng)用,通過組合不同的 generator,可以免除重復(fù)繁瑣的回調(diào)函數(shù)嵌套,并極大地提升錯誤處理的效率。一個Koa應(yīng)用就是一個對象,包含了一個middleware數(shù)組,這個數(shù)組由一組Generator函數(shù)組成。這些函數(shù)負(fù)責(zé)對HTTP請求進(jìn)行各種加工,比如生成緩存、指定代理、請求重定向等等。這些中間件函數(shù)基于 request 請求以一個類似于棧的結(jié)構(gòu)組成并依次執(zhí)行。
Koa 包含了像 content-negotiation(內(nèi)容協(xié)商)、cache freshness(緩存刷新)、proxy support(代理支持)和 redirection(重定向)等常用任務(wù)方法。 與提供龐大的函數(shù)支持不同,Koa只包含很小的一部分,因為Koa并不綁定任何中間件。
?
中間件
Koa的中間件很像Express的中間件,也是對HTTP請求進(jìn)行處理的函數(shù),但是必須是一個Generator函數(shù)。而且,Koa的中間件是一個級聯(lián)式(Cascading)的結(jié)構(gòu),也就是說,屬于是層層調(diào)用,第一個中間件調(diào)用第二個中間件,第二個調(diào)用第三個,以此類推。上游的中間件必須等到下游的中間件返回結(jié)果,才會繼續(xù)執(zhí)行,這點很像遞歸。
中間件通過當(dāng)前應(yīng)用的use方法注冊。
app.use(function* (next){var start = new Date; // (1)yield next; // (2)var ms = new Date - start; // (3)console.log('%s %s - %s', this.method, this.url, ms); // (4) });Generator函數(shù)內(nèi)部使用yield命令,將程序的執(zhí)行權(quán)轉(zhuǎn)交給下一個中間件,即yield next,要等到下一個中間件返回結(jié)果,才會繼續(xù)往下執(zhí)行。只要有一個中間件缺少yield next語句,后面的中間件都不會執(zhí)行,這一點要引起注意。
如果想跳過一個中間件,可以直接在該中間件的第一行語句寫上return yield next。
app.use(function* (next) {if (skip) return yield next; })由于Koa要求中間件唯一的參數(shù)就是next,導(dǎo)致如果要傳入其他參數(shù),必須另外寫一個返回Generator函數(shù)的函數(shù)。
function logger(format) {return function *(next){var str = format.replace(':method', this.method).replace(':url', this.url);console.log(str);yield next;} }app.use(logger(':method :url'));?
路由
可以通過this.path屬性,判斷用戶請求的路徑,從而起到路由作用。
app.use(function* (next) {if (this.path === '/') {this.body = 'we are at home!';} else {yield next;} })復(fù)雜的路由需要安裝koa-router插件。
var app = require('koa')(); var Router = require('koa-router');var myRouter = new Router();myRouter.get('/', function *(next) { //router.get方法的第一個參數(shù)是根路徑,第二個參數(shù)是對應(yīng)的函數(shù)方法。this.response.body = 'Hello World!'; });app.use(myRouter.routes());app.listen(3000);
Koa-router實例提供一系列動詞方法,即一種HTTP動詞對應(yīng)一種方法。典型的動詞方法有以下五種。
- router.get()
- router.post()
- router.put()
- router.del()
- router.patch()
這些動詞方法可以接受兩個參數(shù),第一個是路徑模式,第二個是對應(yīng)的控制器方法(中間件),定義用戶請求該路徑時服務(wù)器行為。
Koa-router允許為路徑統(tǒng)一添加前綴。 var router = new Router({prefix: '/users' });router.get('/', ...); // 等同于"/users" router.get('/:id', ...); // 等同于"/users/:id"?
app.listen(...)
Koa 應(yīng)用并非是一個 1-to-1 表征關(guān)系的 HTTP 服務(wù)器。 一個或多個Koa應(yīng)用可以被掛載到一起組成一個包含單一 HTTP 服務(wù)器的大型應(yīng)用群。
如下為一個綁定3000端口的簡單 Koa 應(yīng)用,其創(chuàng)建并返回了一個 HTTP 服務(wù)器。
var koa = require('koa'); var app = koa(); app.listen(3000);?
app.callback()
返回一個適合 http.createServer() 方法的回調(diào)函數(shù)用來處理請求。 您也可以使用這個回調(diào)函數(shù)將您的app掛載在 Connect/Express 應(yīng)用上。
?
app.use(function)
為應(yīng)用添加指定的中間件,https://github.com/koajs/koa/wiki#middleware,也就是向middleware數(shù)組添加Generator函數(shù)。
?
app.keys=
設(shè)置簽名Cookie密鑰,該密鑰會被傳遞給 KeyGrip。
自己生成秘鑰實例:
app.keys = ['im a newer secret', 'i like turtle']; app.keys = new KeyGrip(['im a newer secret', 'i like turtle'], 'sha256');?
錯誤處理
默認(rèn)情況下Koa會將所有錯誤信息輸出到 stderr,除非 NODE_ENV 是 "test"。為了實現(xiàn)自定義錯誤處理邏輯(比如 centralized logging),您可以添加 "error" 事件監(jiān)聽器。
app.on('error', function(err, ctx){log.error('server error', err, ctx); });?
Context(上下文)
Koa Context 將 node 的 request 和 response 對象封裝在一個單獨的對象里面,其為編寫 web 應(yīng)用和 API 提供了很多有用的方法。
context 在每個 request 請求中被創(chuàng)建,在中間件中作為接收器(receiver)來引用,或者通過 this 標(biāo)識符來引用:
app.use(function *(){this; // is the Contextthis.request; // is a koa Requestthis.response; // is a koa Response });?
CSRF攻擊
CSRF攻擊是指用戶的session被劫持,用來冒充用戶的攻擊。
koa-csrf插件用來防止CSRF攻擊。原理是在session之中寫入一個秘密的token,用戶每次使用POST方法提交數(shù)據(jù)的時候,必須含有這個token,否則就會拋出錯誤。
?
數(shù)據(jù)壓縮
koa-compress模塊可以實現(xiàn)數(shù)據(jù)壓縮。
app.use(require('koa-compress')()) app.use(function* () {this.type = 'text/plain'this.body = fs.createReadStream('filename.txt') })?
API
-
ctx.req
Node 的 request 對象。 -
ctx.res
Node 的 response 對象。 -
ctx.request
Koa 的 Request 對象。 -
ctx.response
Koa 的 Response 對象。 -
ctx.app
應(yīng)用實例引用。 -
ctx.cookies.get(name, [options])
獲得 cookie 中名為 name 的值,options 為可選參數(shù):- 'signed': 如果為 true,表示請求時 cookie 需要進(jìn)行簽名。
-
ctx.cookies.set(name, value, [options])
設(shè)置 cookie 中名為 name 的值,options 為可選參數(shù):- signed: 是否要做簽名
- expires: cookie 有效期時間
- path: cookie 的路徑,默認(rèn)為 /'
- domain: cookie 的域
- secure: false 表示 cookie 通過 HTTP 協(xié)議發(fā)送,true 表示 cookie 通過 HTTPS 發(fā)送。
- httpOnly: true 表示 cookie 只能通過 HTTP 協(xié)議發(fā)送
-
ctx.throw(msg, [status])
拋出包含 .status 屬性的錯誤,默認(rèn)為 500。該方法可以讓 Koa 準(zhǔn)確的響應(yīng)處理狀態(tài)。
?
請求(Request)API
Koa Request 對象是對 node 的 request 進(jìn)一步抽象和封裝,提供了日常 HTTP 服務(wù)器開發(fā)中一些有用的功能。
-
req.header
請求頭對象 -
req.method
請求方法 -
req.method=
設(shè)置請求方法,在實現(xiàn)中間件時非常有用,比如 methodOverride()。 -
req.length
以數(shù)字的形式返回 request 的內(nèi)容長度(Content-Length),或者返回 undefined。 -
req.url
獲得請求url地址。 -
req.url=
設(shè)置請求地址,用于重寫url地址時。 -
req.originalUrl
獲取請求原始地址。 -
req.path
獲取請求路徑名。 -
req.path=
設(shè)置請求路徑名,并保留請求參數(shù)(就是url中?后面的部分)。 -
req.querystring
獲取查詢參數(shù)字符串(url中?后面的部分),不包含 ?。 -
req.querystring=
設(shè)置查詢參數(shù)。 -
req.search
獲取查詢參數(shù)字符串,包含 ?。 -
req.search=
設(shè)置查詢參數(shù)字符串。 -
req.host
-
req.hostname
-
req.charset
-
req.query
將查詢參數(shù)字符串進(jìn)行解析并以對象的形式返回,如果沒有查詢參數(shù)字字符串則返回一個空對象。 -
req.query=
根據(jù)給定的對象設(shè)置查詢參數(shù)字符串。 -
req.fresh
檢查請求緩存是否 "fresh"(內(nèi)容沒有發(fā)生變化)。該方法用于在 If-None-Match / ETag, If-Modified-Since 和 Last-Modified 中進(jìn)行緩存協(xié)調(diào)。當(dāng)在 response headers 中設(shè)置一個或多個上述參數(shù)后,該方法應(yīng)該被使用。
-
req.stale
與 req.fresh 相反。 -
req.protocol
返回請求協(xié)議,"https" 或者 "http"。 當(dāng) app.proxy 設(shè)置為 true 時,支持 X-Forwarded-Host。 -
req.secure
簡化版 this.protocol == "https",用來檢查請求是否通過 TLS 發(fā)送。 -
req.ip
請求遠(yuǎn)程地址。 當(dāng) app.proxy 設(shè)置為 true 時,支持 X-Forwarded-Host。 -
req.is(type)
檢查請求所包含的 "Content-Type" 是否為給定的 type 值。 如果沒有 request body,返回 undefined。 如果沒有 content type,或者匹配失敗,返回 false。 否則返回匹配的 content-type。
-
req.accepts(types)
檢查給定的類型 types(s) 是否可被接受,當(dāng)為 true 時返回最佳匹配,否則返回 false。type 的值可以是一個或者多個 mime 類型字符串。 -
req.acceptsEncodings(encodings)
檢查 encodings 是否可以被接受,當(dāng)為 true 時返回最佳匹配,否則返回 false。 注意:您應(yīng)該在 encodings 中包含 identity。
- req.acceptsCharsets(charsets)
檢查 charsets 是否可以被接受,如果為 true 則返回最佳匹配, 否則返回 false。
-
req.socket
返回請求的socket。 -
req.get(field)
返回請求 header 中對應(yīng) field 的值。
?
響應(yīng)(Response)API
Koa Response 對象是對 node 的 response 進(jìn)一步抽象和封裝,提供了日常 HTTP 服務(wù)器開發(fā)中一些有用的功能。
-
res.header
Response header 對象。 -
res.socket
Response socket。 -
res.status
獲取 response status。不同于 node 在默認(rèn)情況下 res.statusCode 為200,res.status 并沒有賦值。 -
res.statusString
Response status 字符串。 -
res.status=
通過數(shù)字狀態(tài)碼或者不區(qū)分大小寫的字符串來設(shè)置response status. -
res.length=
通過給定值設(shè)置 response Content-Length。 -
res.length
如果 Content-Length 作為數(shù)值存在,或者可以通過 res.body 來進(jìn)行計算,則返回相應(yīng)數(shù)值,否則返回 undefined。 -
res.body
獲得 response body。 -
res.body=
-
res.get(field)
獲取 response header 中字段值,field 不區(qū)分大小寫。
- res.set(field, value)
設(shè)置 response header 字段 field 的值為 value。
- res.set(fields)
使用對象同時設(shè)置 response header 中多個字段的值。
-
res.remove(field)
移除 response header 中字段 filed。 -
res.type
獲取 response Content-Type,不包含像 "charset" 這樣的參數(shù)。 -
res.type=
通過 mime 類型的字符串或者文件擴(kuò)展名設(shè)置 response Content-Type. -
res.redirect(url, [alt])
執(zhí)行 [302] 重定向到對應(yīng) url。 -
res.lastModified
如果存在 Last-Modified,則以 Date 的形式返回。 -
res.lastModified=
以 UTC 格式設(shè)置 Last-Modified。您可以使用 Date 或 date 字符串來進(jìn)行設(shè)置。 -
res.append(field, val)
在 header 的 field 后面 追加 val。 -
res.vary(field)
相當(dāng)于執(zhí)行res.append('Vary', field)。
-
轉(zhuǎn)載于:https://www.cnblogs.com/zourong/p/6048157.html
總結(jié)
- 上一篇: Alpha版本项目展示要求
- 下一篇: TortoiseSVN搭载