請求(Request)
此係列文章的應用示例已釋出於 GitHub: koa-docs-Zh-CN. 可以 Fork 幫助改進或 Star 關注更新. 歡迎 Star.
Koa Request
物件是在 node 的 vanilla 請求物件之上的抽象,提供了諸多對 HTTP 伺服器開發有用的功能。
API
request.header
請求標頭物件。
request.header=
設定請求標頭物件。
request.headers
請求標頭物件。別名為 request.header
.
request.headers=
設定請求標頭物件。別名為 request.header=
.
request.method
請求方法。
request.method=
設定請求方法,對於實現諸如 methodOverride()
的中介軟體是有用的。
request.length
返回以數字返回請求的 Content-Length,或 undefined
。
request.url
獲取請求 URL.
request.url=
設定請求 URL, 對 url 重寫有用。
request.originalUrl
獲取請求原始URL。
request.origin
獲取URL的來源,包括 protocol
和 host
。
ctx.request.origin
// => http://example.com
request.href
獲取完整的請求URL,包括 protocol
,host
和 url
。
ctx.request.href;
// => http://example.com/foo/bar?q=1
request.path
獲取請求路徑名。
request.path=
設定請求路徑名,並在存在時保留查詢字串。
request.querystring
根據 ?
獲取原始查詢字串.
request.querystring=
設定原始查詢字串。
request.search
使用 ?
獲取原始查詢字串。
request.search=
設定原始查詢字串。
request.host
獲取當前主機(hostname:port)。當 app.proxy
是 true 時支援 X-Forwarded-Host
,否則使用 Host
。
request.hostname
存在時獲取主機名。當 app.proxy
是 true 時支援 X-Forwarded-Host
,否則使用 Host
。
如果主機是 IPv6, Koa 解析到
WHATWG URL API,
注意 這可能會影響效能。
request.URL
獲取 WHATWG 解析的 URL 物件。
request.type
獲取請求 Content-Type
不含引數 “charset”。
const ct = ctx.request.type;
// => "image/png"
request.charset
在存在時獲取請求字符集,或者 undefined
:
ctx.request.charset;
// => "utf-8"
request.query
獲取解析的查詢字串, 當沒有查詢字串時,返回一個空物件。請注意,此 getter 不 支援巢狀解析。
例如 “color=blue&size=small”:
{
color: `blue`,
size: `small`
}
request.query=
將查詢字串設定為給定物件。 請注意,此 setter 不 支援巢狀物件。
ctx.query = { next: `/login` };
request.fresh
檢查請求快取是否“新鮮”,也就是內容沒有改變。此方法用於 If-None-Match
/ ETag
, 和 If-Modified-Since
和 Last-Modified
之間的快取協商。 在設定一個或多個這些響應頭後應該引用它。
// 新鮮度檢查需要狀態20x或304
ctx.status = 200;
ctx.set(`ETag`, `123`);
// 快取是好的
if (ctx.fresh) {
ctx.status = 304;
return;
}
// 快取是陳舊的
// 獲取新資料
ctx.body = await db.find(`something`);
request.stale
相反與 request.fresh
.
request.protocol
返回請求協議,“https” 或 “http”。當 app.proxy
是 true 時支援 X-Forwarded-Proto
。
request.secure
通過 ctx.protocol == "https"
來檢查請求是否通過 TLS 發出。
request.ip
請求遠端地址。 當 app.proxy
是 true 時支援 X-Forwarded-Proto
。
request.ips
當 X-Forwarded-For
存在並且 app.proxy
被啟用時,這些 ips 的陣列被返回,從上游 – >下游排序。 禁用時返回一個空陣列。
request.subdomains
將子域返回為陣列。
子域是應用程式主域之前主機的點分隔部分。預設情況下,應用程式的域名假定為主機的最後兩個部分。這可以通過設定 app.subdomainOffset
來更改。
例如,如果域名為“tobi.ferrets.example.com”:
如果 app.subdomainOffset
未設定, ctx.subdomains
是 ["ferrets", "tobi"]
.
如果 app.subdomainOffset
是 3, ctx.subdomains
是 ["tobi"]
.
request.is(types…)
檢查傳入請求是否包含 Content-Type
頭欄位, 並且包含任意的 mime type
。
如果沒有請求主體,返回 null
。
如果沒有內容型別,或者匹配失敗,則返回 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`
// 當 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
例如,如果要確保僅將影像傳送到給定路由:
if (ctx.is(`image/*`)) {
// 處理
} else {
ctx.throw(415, `images only!`);
}
內容協商
Koa的 request
物件包括由 accepts 和 negotiator 提供的有用的內容協商實體。
這些實用程式是:
request.accepts(types)
request.acceptsEncodings(types)
request.acceptsCharsets(charsets)
request.acceptsLanguages(langs)
如果沒有提供型別,則返回 所有 可接受的型別。
如果提供多種型別,將返回最佳匹配。 如果沒有找到匹配項,則返回一個false
,你應該向客戶端傳送一個406 "Not Acceptable"
響應。
如果接收到任何型別的接收頭,則會返回第一個型別。 因此,你提供的型別的順序很重要。
request.accepts(types)
檢查給定的 type(s)
是否可以接受,如果 true
,返回最佳匹配,否則為 false
。 type
值可能是一個或多個 mime 型別的字串,如 application/json
,副檔名稱如 json
,或陣列 ["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"
你可以根據需要多次呼叫 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`);
}
request.acceptsEncodings(encodings)
檢查 encodings
是否可以接受,返回最佳匹配為 true
,否則為 false
。 請注意,您應該將identity
作為編碼之一!
// Accept-Encoding: gzip
ctx.acceptsEncodings(`gzip`, `deflate`, `identity`);
// => "gzip"
ctx.acceptsEncodings([`gzip`, `deflate`, `identity`]);
// => "gzip"
當沒有給出引數時,所有接受的編碼將作為陣列返回:
// Accept-Encoding: gzip, deflate
ctx.acceptsEncodings();
// => ["gzip", "deflate", "identity"]
請注意,如果客戶端顯式地傳送 identity;q=0
,那麼 identity
編碼(這意味著沒有編碼)可能是不可接受的。 雖然這是一個邊緣的情況,你仍然應該處理這種方法返回 false
的情況。
request.acceptsCharsets(charsets)
檢查 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"
當沒有引數被賦予所有被接受的字符集將作為陣列返回:
// Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5
ctx.acceptsCharsets();
// => ["utf-8", "utf-7", "iso-8859-1"]
request.acceptsLanguages(langs)
檢查 langs
是否可以接受,如果為 true
,返回最佳匹配,否則為 false
。
// Accept-Language: en;q=0.8, es, pt
ctx.acceptsLanguages(`es`, `en`);
// => "es"
ctx.acceptsLanguages([`en`, `es`]);
// => "es"
當沒有引數被賦予所有接受的語言將作為陣列返回:
// Accept-Language: en;q=0.8, es, pt
ctx.acceptsLanguages();
// => ["es", "pt", "en"]
request.idempotent
檢查請求是否是冪等的。
request.socket
返回請求套接字。
request.get(field)
返回請求標頭。
如果這篇文章對您有幫助, 感謝 下方點贊 或 Star GitHub: koa-docs-Zh-CN 支援, 謝謝.