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