Koa Request 對象是在 node 的 vanilla 請求對象之上的抽象,提供了諸多對 HTTP 服務(wù)器開發(fā)有用的功能。
請求標(biāo)頭對象。這與 node http.IncomingMessage 上的 headers 字段相同
設(shè)置請求標(biāo)頭對象。
請求標(biāo)頭對象。別名為 request.header.
設(shè)置請求標(biāo)頭對象。別名為 request.header=.
請求方法。
設(shè)置請求方法,對于實現(xiàn)諸如 methodOverride() 的中間件是有用的。
返回以數(shù)字返回請求的 Content-Length,或 undefined。
獲取請求 URL.
設(shè)置請求 URL, 對 url 重寫有用。
獲取請求原始URL。
獲取URL的來源,包括 protocol 和 host。
ctx.request.origin
// => http://example.com
獲取完整的請求URL,包括 protocol,host 和 url。
ctx.request.href;
// => http://example.com/foo/bar?q=1
獲取請求路徑名。
設(shè)置請求路徑名,并在存在時保留查詢字符串。
根據(jù) ? 獲取原始查詢字符串.
設(shè)置原始查詢字符串。
使用 ? 獲取原始查詢字符串。
設(shè)置原始查詢字符串。
獲取當(dāng)前主機(hostname:port)。當(dāng) app.proxy 是 true 時支持 X-Forwarded-Host,否則使用 Host。
存在時獲取主機名。當(dāng) app.proxy 是 true 時支持 X-Forwarded-Host,否則使用 Host。
如果主機是 IPv6, Koa 解析到 WHATWG URL API, 注意 這可能會影響性能。
獲取 WHATWG 解析的 URL 對象。
獲取請求 Content-Type 不含參數(shù) "charset"。
const ct = ctx.request.type;
// => "image/png"
在存在時獲取請求字符集,或者 undefined:
ctx.request.charset;
// => "utf-8"
獲取解析的查詢字符串, 當(dāng)沒有查詢字符串時,返回一個空對象。請注意,此 getter _不_ 支持嵌套解析。
例如 "color=blue&size=small":
{
color: 'blue',
size: 'small'
}
將查詢字符串設(shè)置為給定對象。 請注意,此 setter _不_ 支持嵌套對象。
ctx.query = { next: '/login' };
檢查請求緩存是否“新鮮”,也就是內(nèi)容沒有改變。此方法用于 If-None-Match / ETag, 和 If-Modified-Since 和 Last-Modified 之間的緩存協(xié)商。 在設(shè)置一個或多個這些響應(yīng)頭后應(yīng)該引用它。
// 新鮮度檢查需要狀態(tài)20x或304
ctx.status = 200;
ctx.set('ETag', '123');
// 緩存是好的
if (ctx.fresh) {
ctx.status = 304;
return;
}
// 緩存是陳舊的
// 獲取新數(shù)據(jù)
ctx.body = await db.find('something');
相反與 request.fresh.
返回請求協(xié)議,“https” 或 “http”。當(dāng) app.proxy 是 true 時支持 X-Forwarded-Proto。
通過 ctx.protocol == "https" 來檢查請求是否通過 TLS 發(fā)出。
請求遠(yuǎn)程地址。 當(dāng) app.proxy 是 true 時支持 X-Forwarded-Proto。
當(dāng) X-Forwarded-For 存在并且 app.proxy 被啟用時,這些 ips 的數(shù)組被返回,從上游 - >下游排序。 禁用時返回一個空數(shù)組。
例如,如果值是 "client, proxy1, proxy2",將會得到數(shù)組 ["client", "proxy1", "proxy2"]。
大多數(shù)反向代理(nginx)都通過 proxy_add_x_forwarded_for 設(shè)置了 x-forwarded-for,這帶來了一定的安全風(fēng)險。惡意攻擊者可以通過偽造 X-Forwarded-For 請求標(biāo)頭來偽造客戶端的ip地址。 客戶端發(fā)送的請求具有 'forged' 的 X-Forwarded-For 請求標(biāo)頭。 在由反向代理轉(zhuǎn)發(fā)之后,request.ips 將是 ['forged', 'client', 'proxy1', 'proxy2']。
Koa 提供了兩種方式來避免被繞過。
如果您可以控制反向代理,則可以通過調(diào)整配置來避免繞過,或者使用 koa 提供的 app.proxyIpHeader 來避免讀取 x-forwarded-for 獲取 ips。
const app = new Koa({
proxy: true,
proxyIpHeader: 'X-Real-IP',
});
如果您確切知道服務(wù)器前面有多少個反向代理,則可以通過配置 app.maxIpsCount 來避免讀取用戶的偽造的請求標(biāo)頭:
const app = new Koa({
proxy: true,
maxIpsCount: 1, // 服務(wù)器前只有一個代理
});
// request.header['X-Forwarded-For'] === [ '127.0.0.1', '127.0.0.2' ];
// ctx.ips === [ '127.0.0.2' ];
將子域返回為數(shù)組。
子域是應(yīng)用程序主域之前主機的點分隔部分。默認(rèn)情況下,應(yīng)用程序的域名假定為主機的最后兩個部分。這可以通過設(shè)置 app.subdomainOffset 來更改。
例如,如果域名為“tobi.ferrets.example.com”:
如果 app.subdomainOffset 未設(shè)置, ctx.subdomains 是 ["ferrets", "tobi"]. 如果 app.subdomainOffset 是 3, ctx.subdomains 是 ["tobi"].
檢查傳入請求是否包含 Content-Type 頭字段, 并且包含任意的 mime type。 如果沒有請求主體,返回 null。 如果沒有內(nèi)容類型,或者匹配失敗,則返回 false。 反之則返回匹配的 content-type。
// 使用 Content-Type: text/html; charset=utf-8
ctx.is('html'); // => 'html'
ctx.is('text/html'); // => 'text/html'
ctx.is('text/*', 'text/html'); // => 'text/html'
// 當(dāng) Content-Type 是 application/json 時
ctx.is('json', 'urlencoded'); // => 'json'
ctx.is('application/json'); // => 'application/json'
ctx.is('html', 'application/*'); // => 'application/json'
ctx.is('html'); // => false
例如,如果要確保僅將圖像發(fā)送到給定路由:
if (ctx.is('image/*')) {
// 處理
} else {
ctx.throw(415, 'images only!');
}
Koa的 request 對象包括由 accepts 和 negotiator 提供的有用的內(nèi)容協(xié)商實體。
這些實用程序是:
如果沒有提供類型,則返回 所有 可接受的類型。
如果提供多種類型,將返回最佳匹配。 如果沒有找到匹配項,則返回一個false,你應(yīng)該向客戶端發(fā)送一個406 "Not Acceptable" 響應(yīng)。
如果接收到任何類型的接收頭,則會返回第一個類型。 因此,你提供的類型的順序很重要。
檢查給定的 type(s) 是否可以接受,如果 true,返回最佳匹配,否則為 false。 type 值可能是一個或多個 mime 類型的字符串,如 application/json,擴(kuò)展名稱如 json,或數(shù)組 ["json", "html", "text/plain"]。
// Accept: text/html
ctx.accepts('html');
// => "html"
// Accept: text/*, application/json
ctx.accepts('html');
// => "html"
ctx.accepts('text/html');
// => "text/html"
ctx.accepts('json', 'text');
// => "json"
ctx.accepts('application/json');
// => "application/json"
// Accept: text/*, application/json
ctx.accepts('image/png');
ctx.accepts('png');
// => false
// Accept: text/*;q=.5, application/json
ctx.accepts(['html', 'json']);
ctx.accepts('html', 'json');
// => "json"
// No Accept header
ctx.accepts('html', 'json');
// => "html"
ctx.accepts('json', 'html');
// => "json"
你可以根據(jù)需要多次調(diào)用 ctx.accepts(),或使用 switch:
switch (ctx.accepts('json', 'html', 'text')) {
case 'json': break;
case 'html': break;
case 'text': break;
default: ctx.throw(406, 'json, html, or text only');
}
檢查 encodings 是否可以接受,返回最佳匹配為 true,否則為 false。 請注意,您應(yīng)該將identity 作為編碼之一!
// Accept-Encoding: gzip
ctx.acceptsEncodings('gzip', 'deflate', 'identity');
// => "gzip"
ctx.acceptsEncodings(['gzip', 'deflate', 'identity']);
// => "gzip"
當(dāng)沒有給出參數(shù)時,所有接受的編碼將作為數(shù)組返回:
// Accept-Encoding: gzip, deflate
ctx.acceptsEncodings();
// => ["gzip", "deflate", "identity"]
請注意,如果客戶端顯式地發(fā)送 identity;q=0,那么 identity 編碼(這意味著沒有編碼)可能是不可接受的。 雖然這是一個邊緣的情況,你仍然應(yīng)該處理這種方法返回 false 的情況。
檢查 charsets 是否可以接受,在 true 時返回最佳匹配,否則為 false。
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
ctx.acceptsCharsets('utf-8', 'utf-7');
// => "utf-8"
ctx.acceptsCharsets(['utf-7', 'utf-8']);
// => "utf-8"
當(dāng)沒有參數(shù)被賦予所有被接受的字符集將作為數(shù)組返回:
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
ctx.acceptsCharsets();
// => ["utf-8", "utf-7", "iso-8859-1"]
檢查 langs 是否可以接受,如果為 true,返回最佳匹配,否則為 false。
// Accept-Language: en;q=0.8, es, pt
ctx.acceptsLanguages('es', 'en');
// => "es"
ctx.acceptsLanguages(['en', 'es']);
// => "es"
當(dāng)沒有參數(shù)被賦予所有接受的語言將作為數(shù)組返回:
// Accept-Language: en;q=0.8, es, pt
ctx.acceptsLanguages();
// => ["es", "pt", "en"]
檢查請求是否是冪等的。
返回請求套接字。
返回請求標(biāo)頭。不區(qū) field 的分大小寫.
更多建議: