node.js 的新一代 Web 框架

簡介

Koa 是由 Express 團隊設計的新 Web 框架,旨在成為更精簡、更具表達力且更強大的 Web 應用程式和 API 基礎。藉由利用非同步函式,Koa 讓您可以放棄回呼,並大幅提升錯誤處理。Koa 的核心不包含任何中間件,並提供一套優雅的方法,讓撰寫伺服器變得快速又令人愉快。

安裝

Koa 需要 node v12 或更高版本才能支援 ES2015 和非同步函式。

您可以使用您最愛的版本管理員快速安裝支援的 node 版本

$ nvm install 7
$ npm i koa
$ node my-koa-app.js

應用

Koa 應用程式是一個包含中間件函式陣列的物件,這些函式以堆疊的方式組成並在請求時執行。Koa 類似於您可能曾接觸過的許多其他中間件系統,例如 Ruby 的 Rack、Connect 等 - 但一個關鍵的設計決策是在低階中間件層提供高階的「糖衣」。這改善了互操作性、穩健性,並讓撰寫中間件變得更令人愉快。

這包括用於內容協商、快取新鮮度、代理支援和重新導向等常見任務的方法。儘管提供了相當大量的有用方法,但 Koa 仍維持精簡的體積,因為沒有捆綁任何中間件。

必要的 hello world 應用程式

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3000);

串接

Koa 中間件以更傳統的方式串接,就像您可能習慣於使用類似工具一樣 - 以前很難使用 node 的回呼讓使用者使用起來更友善。然而,透過非同步函式,我們可以實現「真正的」中間件。與 Connect 的實作形成對比,Connect 的實作只是將控制權傳遞給一系列函式,直到其中一個函式傳回,而 Koa 會呼叫「下游」,然後控制權再流回「上游」。

以下範例會回應「Hello World」,但首先,請求會流經 x-response-timelogging 中間件,以標記請求開始的時間,然後透過回應中間件傳遞控制權。當中間件呼叫 next() 時,函式會暫停並將控制權傳遞給定義的下一中間件。當沒有更多中間件要執行下游時,堆疊會解開,每個中間件都會繼續執行其上游行為。

const Koa = require('koa');
const app = new Koa();

// logger

app.use(async (ctx, next) => {
  await next();
  const rt = ctx.response.get('X-Response-Time');
  console.log(`${ctx.method} ${ctx.url} - ${rt}`);
});

// x-response-time

app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
});

// response

app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3000);

設定

應用程式設定是 app 執行個體上的屬性,目前支援下列設定

app.listen(...)

Koa 應用程式並非 HTTP 伺服器的 1 對 1 表示。一個或多個 Koa 應用程式可以一起掛載,以形成具有單一 HTTP 伺服器的較大應用程式。

建立並傳回一個 HTTP 伺服器,將給定的引數傳遞給 Server#listen()。這些引數記錄在 nodejs.org 上。以下是繫結到埠 3000 的無用 Koa 應用程式

const Koa = require('koa');
const app = new Koa();
app.listen(3000);

app.listen(...) 方法只是以下內容的語法糖

const http = require('http');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);

這表示您可以將相同的應用程式同時作為 HTTP 和 HTTPS 或在多個位址上執行

const http = require('http');
const https = require('https');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
https.createServer(app.callback()).listen(3001);

app.callback()

傳回適合 http.createServer() 方法的回呼函式,以處理要求。您也可以使用這個回呼函式在 Connect/Express 應用程式中掛載您的 Koa 應用程式。

app.use(function)

將給定的中間件函式新增到這個應用程式。app.use() 傳回 this,因此可以串接。

app.use(someMiddleware)
app.use(someOtherMiddleware)
app.listen(3000)

與下列相同

app.use(someMiddleware)
  .use(someOtherMiddleware)
  .listen(3000)

請參閱 中間件 以取得更多資訊。

app.keys=

設定已簽署的 Cookie 金鑰。

這些金鑰會傳遞給 KeyGrip,但您也可以傳遞您自己的 KeyGrip 實例。例如,下列為可接受的

app.keys = ['OEK5zjaAMPc3L6iK7PyUjCOziUH3rsrMKB9u8H07La1SkfwtuBoDnHaaPCkG5Brg', 'MNKeIebviQnCPo38ufHcSfw3FFv8EtnAe1xE02xkN1wkCV1B2z126U44yk2BQVK7'];
app.keys = new KeyGrip(['OEK5zjaAMPc3L6iK7PyUjCOziUH3rsrMKB9u8H07La1SkfwtuBoDnHaaPCkG5Brg', 'MNKeIebviQnCPo38ufHcSfw3FFv8EtnAe1xE02xkN1wkCV1B2z126U44yk2BQVK7'], 'sha256');

基於安全考量,請確保金鑰夠長且隨機。

這些金鑰可以輪替,並在使用 { signed: true } 選項簽署 Cookie 時使用

ctx.cookies.set('name', 'tobi', { signed: true });

app.context

app.contextctx 建立的原型。您可以透過編輯 app.context,將其他屬性新增到 ctx。這對於在 ctx 中新增屬性或方法,以在整個應用程式中使用,非常有用,這可能會提升效能(無中間件)和/或更容易(較少的 require()),但缺點是更依賴 ctx,這可能會被視為反模式。

例如,從 ctx 中新增資料庫參考

app.context.db = db();

app.use(async ctx => {
  console.log(ctx.db);
});

注意

錯誤處理

預設情況下,除非 app.silenttrue,否則會將所有錯誤輸出至 stderr。當 err.status404err.exposetrue 時,預設錯誤處理常式也不會輸出錯誤。若要執行自訂錯誤處理邏輯(例如集中式記錄),您可以新增一個「error」事件監聽器

app.on('error', err => {
  log.error('server error', err)
});

如果錯誤在 req/res 循環中,而且無法回應客戶端,則也會傳遞 Context 執行個體

app.on('error', (err, ctx) => {
  log.error('server error', err, ctx)
});

當錯誤發生仍有可能回應客戶端(也就是尚未將資料寫入 socket)時,Koa 會適當地回應 500「內部伺服器錯誤」。在任一種情況下,都會發出應用程式層級的「error」以進行記錄。

內容

Koa Context 將 Node.js 的 requestresponse 物件封裝成一個單一物件,提供許多有用的方法來撰寫 Web 應用程式和 API。這些操作在 HTTP 伺服器開發中使用非常頻繁,因此會在此層級而非較高層級的架構中新增,這將強迫中間件重新實作此常見功能。

每個要求都會建立一個 Context,並在中間件中參考為接收器或 ctx 識別碼,如下列程式碼片段所示

app.use(async ctx => {
  ctx; // is the Context
  ctx.request; // is a Koa Request
  ctx.response; // is a Koa Response
});

為了方便,許多 context 的存取器和方法僅委派給其等效的 ctx.requestctx.response,否則就是相同的。例如,ctx.typectx.length 委派給 response 物件,而 ctx.pathctx.method 委派給 request

API

Context 特定的方法和存取器。

ctx.req

Node.js 的 request 物件。

ctx.res

Node.js 的 response 物件。

不支援繞過 Koa 的回應處理。避免使用下列 Node.js 屬性

ctx.request

Koa Request 物件。

ctx.response

Koa Response 物件。

ctx.state

建議的命名空間,用於透過中間件和前端檢視傳遞資訊。

ctx.state.user = await User.find(id);

ctx.app

應用程式執行個體參考。

ctx.app.emit

Koa 應用程式延伸內部 EventEmitterctx.app.emit 會發出一個事件,其類型由第一個引數定義。對於每個事件,您可以串接「監聽器」,這是一個在事件發出時呼叫的函式。請參閱 錯誤處理文件 以取得更多資訊。

ctx.cookies.get(name, [options])

取得 cookie nameoptions

Koa 使用 cookies 模組,其中選項會直接傳遞。

ctx.cookies.set(name, value, [options])

設定 cookie namevalueoptions

Koa 使用 cookies 模組,其中選項會直接傳遞。

ctx.throw([狀態], [訊息], [屬性])

輔助方法,用於擲回預設為 500.status 屬性的錯誤,這將允許 Koa 適當地回應。允許以下組合

ctx.throw(400);
ctx.throw(400, 'name required');
ctx.throw(400, 'name required', { user: user });

例如,ctx.throw(400, '需要名稱') 等同於

const err = new Error('name required');
err.status = 400;
err.expose = true;
throw err;

請注意,這些是使用者層級錯誤,並標記為 err.expose,表示訊息適合於客戶端回應,這通常不適用於錯誤訊息,因為您不希望洩漏失敗詳細資料。

您也可以傳遞 屬性物件,它會合併到錯誤中,這對於裝飾報告給上游請求者的機器友善錯誤很有用。

ctx.throw(401, 'access_denied', { user: user });

Koa 使用 http-errors 來建立錯誤。狀態只能傳遞為第一個參數。

ctx.assert(值, [狀態], [訊息], [屬性])

!值 時,輔助方法會擲回類似於 .throw() 的錯誤。類似於 Node 的 assert() 方法。

ctx.assert(ctx.state.user, 401, 'User not found. Please login!');

Koa 使用 http-assert 進行斷言。

ctx.respond

若要繞過 Koa 內建的回應處理,您可以明確設定 ctx.respond = false;。如果您想要寫入原始 res 物件,而不是讓 Koa 為您處理回應,請使用此方法。

請注意,Koa 支援使用此方法。這可能會破壞 Koa 中介軟體和 Koa 本身的預期功能。使用此屬性被視為一種破解,而且僅方便於那些希望在 Koa 中使用傳統 fn(req, res) 函式和中介軟體的人。

請求別名

下列存取器和別名 Request 等效項

回應別名

下列存取器和別名 Response 等效項

請求

Koa Request 物件是節點原生請求物件的抽象,提供對日常 HTTP 伺服器開發有用的額外功能。

API

request.header

請求標頭物件。這與節點的 headers 欄位相同 http.IncomingMessage

request.header=

設定請求標頭物件。

request.headers

請求標頭物件。別名為 request.header

request.headers=

設定請求標頭物件。別名為 request.header=

request.method

請求方法。

request.method=

設定請求方法,用於實作中介軟體,例如 methodOverride()

request.length

如果存在,則傳回請求內容長度作為數字,否則傳回 undefined

request.url

取得請求 URL。

request.url=

設定請求 URL,用於 URL 改寫。

request.originalUrl

取得請求原始 URL。

request.origin

取得 URL 起始位置,包括 protocolhost

ctx.request.origin
// => http://example.com

request.href

取得完整請求 URL,包括 protocolhosturl

ctx.request.href;
// => http://example.com/foo/bar?q=1

request.path

取得請求路徑名稱。

request.path=

設定請求路徑名稱並保留現有的查詢字串。

request.querystring

取得不含 ? 的原始查詢字串。

request.querystring=

設定原始查詢字串。

取得包含 ? 的原始查詢字串。

request.search=

設定原始查詢字串。

request.host

如果存在,取得主機 (hostname:port)。當 app.proxytrue 時,支援 X-Forwarded-Host,否則使用 Host

request.hostname

如果存在,取得主機名稱。當 app.proxytrue 時,支援 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 / ETagIf-Modified-SinceLast-Modified 之間的快取協商。應該在設定其中一個或多個這些回應標頭之後參照它。

// freshness check requires status 20x or 304
ctx.status = 200;
ctx.set('ETag', '123');

// cache is ok
if (ctx.fresh) {
  ctx.status = 304;
  return;
}

// cache is stale
// fetch new data
ctx.body = await db.find('something');

request.stale

request.fresh 的反向。

request.protocol

傳回請求協定,為「https」或「http」。當 app.proxytrue 時,支援 X-Forwarded-Proto

request.secure

ctx.protocol == "https" 的簡寫,用於檢查請求是否透過 TLS 發出。

request.ip

請求遠端位址。當 app.proxytrue 時,支援 X-Forwarded-For

request.ips

X-Forwarded-For 存在且 app.proxy 已啟用時,會傳回這些 IP 的陣列,由上游 -> 下游排序。當停用時,會傳回空陣列。

例如,如果值為「client, proxy1, proxy2」,你會收到陣列 ["client", "proxy1", "proxy2"]

大部分的反向代理程式 (nginx) 會透過 proxy_add_x_forwarded_for 設定 x-forwarded-for,這會造成一定的安全性風險。惡意攻擊者可以透過偽造 X-Forwarded-For 請求標頭來偽造客戶端的 IP 位址。客戶端發出的請求有一個 X-Forwarded-For 請求標頭為「偽造」。在反向代理程式轉發後,request.ips 會變成 ['偽造', '客戶端', 'proxy1', 'proxy2']。

Koa 提供兩個選項來避免被繞過。

如果你可以控制反向代理程式,你可以透過調整設定來避免被繞過,或使用 koa 提供的 app.proxyIpHeader 來避免讀取 x-forwarded-for 來取得 IP。

  const app = new Koa({
    proxy: true,
    proxyIpHeader: 'X-Real-IP',
  });

如果你確實知道伺服器前面有幾個反向代理程式,你可以透過設定 app.maxIpsCount 來避免讀取使用者偽造的請求標頭。

  const app = new Koa({
    proxy: true,
    maxIpsCount: 1, // only one proxy in front of the server
  });

  // request.header['X-Forwarded-For'] === [ '127.0.0.1', '127.0.0.2' ];
  // ctx.ips === [ '127.0.0.2' ];

request.subdomains

傳回子網域作為陣列。

子網域是應用程式主網域之前的點分隔主機部分。預設情況下,應用程式的網域假設是主機的最後兩個部分。這可以透過設定 app.subdomainOffset 來變更。

例如,如果網域是「tobi.ferrets.example.com」:如果未設定 app.subdomainOffsetctx.subdomains 會是 ["ferrets", "tobi"]。如果 app.subdomainOffset 是 3,ctx.subdomains 會是 ["tobi"]

request.is(types...)

檢查傳入請求是否包含「Content-Type」標頭欄位,以及是否包含任何給定的 MIME type。如果沒有請求主體,會傳回 null。如果沒有內容類型,或比對失敗,會傳回 false。否則,會傳回比對的內容類型。

// With Content-Type: text/html; charset=utf-8
ctx.is('html'); // => 'html'
ctx.is('text/html'); // => 'text/html'
ctx.is('text/*', 'text/html'); // => 'text/html'

// When Content-Type is 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/*')) {
  // process
} else {
  ctx.throw(415, 'images only!');
}

內容協商

Koa 的 request 物件包含由 acceptsnegotiator 提供的實用內容協商工具。這些工具是

如果沒有提供類型,將傳回所有可接受的類型。

如果提供了多個類型,將傳回最佳相符項。如果找不到相符項,將傳回 false,您應該傳送 406 "Not Acceptable" 回應給客戶端。

在缺少接受標頭且任何類型都可接受的情況下,將傳回第一個類型。因此,您提供的類型的順序很重要。

request.accepts(types)

檢查給定的 type(s) 是否可接受,如果為真則傳回最佳相符項,否則為 falsetype 值可以是一個或多個 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 (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 是否可接受,如果為真則傳回最佳相符項,否則為 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 是否可接受,如果為真則傳回最佳相符項,否則為 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 是否可接受,如果為真則傳回最佳相符項,否則為 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

傳回請求 Socket。

request.get(field)

傳回不區分大小寫的 field 的請求標頭。

回應

Koa Response 物件是建立在 Node 的香草回應物件之上的抽象化,提供對日常 HTTP 伺服器開發有用的額外功能。

API

response.header

回應標頭物件。

response.headers

回應標頭物件。別名為 response.header

response.socket

回應 socket。指向 net.Socket 實例,如同 request.socket

response.status

取得回應狀態。預設情況下,response.status 設為 404,這與 node 的 res.statusCode 預設為 200 不同。

response.status=

透過數字代碼設定回應狀態

注意:不用太擔心記住這些字串,如果你打錯字,會擲出錯誤,顯示此清單,以便你可以更正。

由於 response.status 預設設為 404,因此要傳送沒有主體且狀態不同的回應,請執行下列動作

ctx.response.status = 200;

// Or whatever other status
ctx.response.status = 204;

response.message

取得回應狀態訊息。預設情況下,response.messageresponse.status 關聯。

response.message=

將回應狀態訊息設定為指定值。

response.length=

將回應 Content-Length 設定為指定值。

response.length

在存在時,以數字形式傳回回應 Content-Length,或在可能時從 ctx.body 推論,或 undefined

response.body

取得回應主體。

response.body=

將回應主體設定為下列其中一項

如果尚未設定 response.status,Koa 會自動將狀態設定為 200204,具體取決於 response.body。特別是,如果尚未設定 response.body 或已設定為 nullundefined,Koa 會自動將 response.status 設定為 204。如果您真的想要傳送沒有內容的回應,但狀態不同,您應該以下列方式覆寫 204 狀態

// This must be always set first before status, since null | undefined
// body automatically sets the status to 204
ctx.body = null;
// Now we override the 204 status with the desired one
ctx.status = 200;

Koa 沒有防範所有可能作為回應主體的內容 -- 函式無法有意義地序列化,傳回布林值可能根據您的應用程式有意義,而錯誤雖然有效,但可能無法如預期般運作,因為錯誤的某些屬性不可列舉。我們建議在您的應用程式中新增中間件,以宣告每個應用程式的主體類型。範例中間件可能是

app.use(async (ctx, next) => {
  await next()

  ctx.assert.equal('object', typeof ctx.body, 500, 'some dev did something wrong')
})

字串

Content-Type 預設為 text/html 或 text/plain,兩者預設字元集為 utf-8。Content-Length 欄位也已設定。

緩衝區

Content-Type 預設為 application/octet-stream,Content-Length 也已設定。

串流

Content-Type 預設為 application/octet-stream。

每當串流設定為回應主體時,.onerror 會自動新增為 error 事件的監聽器,以捕捉任何錯誤。此外,每當要求關閉(甚至過早關閉)時,串流都會被銷毀。如果您不想要這兩個功能,請不要直接將串流設定為主體。例如,在代理中將主體設定為 HTTP 串流時,您可能不想要這樣做,因為這會銷毀基礎連線。

請參閱:https://github.com/koajs/koa/pull/612 以取得更多資訊。

以下是串流錯誤處理的範例,不會自動銷毀串流

const PassThrough = require('stream').PassThrough;

app.use(async ctx => {
  ctx.body = someHTTPStream.on('error', (err) => ctx.onerror(err)).pipe(PassThrough());
});

物件

Content-Type 預設為 application/json。這包括一般物件 { foo: 'bar' } 和陣列 ['foo', 'bar']

response.get(field)

取得不區分大小寫的 field 的回應標頭欄位值。

const etag = ctx.response.get('ETag');

response.has(field)

如果名稱所識別的標頭目前在傳出的標頭中設定,則傳回 true。標頭名稱比對不區分大小寫。

const rateLimited = ctx.response.has('X-RateLimit-Limit');

response.set(field, value)

將回應標頭 field 設定為 value

ctx.set('Cache-Control', 'no-cache');

response.append(field, value)

附加標頭 field,其值為 val

ctx.append('Link', '<http://127.0.0.1/>');

response.set(fields)

使用物件設定多個回應標頭 fields

ctx.set({
  'Etag': '1234',
  'Last-Modified': date
});

這會委派給 setHeader,它會透過指定的鍵設定或更新標頭,而不重設整個標頭。

response.remove(field)

移除標頭 field

response.type

取得回應的 Content-Type,不含參數,例如「charset」。

const ct = ctx.type;
// => "image/png"

response.type=

透過 MIME 字串或檔案副檔名設定回應的 Content-Type

ctx.type = 'text/plain; charset=utf-8';
ctx.type = 'image/png';
ctx.type = '.png';
ctx.type = 'png';

注意:在適當的時候,會為您選擇 charset,例如 response.type = 'html' 預設為「utf-8」。如果您需要覆寫 charset,請使用 ctx.set('Content-Type', 'text/html') 直接將回應標頭欄位設定為值。

response.is(types...)

ctx.request.is() 非常類似。檢查回應類型是否為所提供類型之一。這對於建立用於處理回應的中介軟體特別有用。

例如,這是一個中介軟體,它會壓縮所有 HTML 回應,但串流除外。

const minify = require('html-minifier');

app.use(async (ctx, next) => {
  await next();

  if (!ctx.response.is('html')) return;

  let body = ctx.body;
  if (!body || body.pipe) return;

  if (Buffer.isBuffer(body)) body = body.toString();
  ctx.body = minify(body);
});

response.redirect(url, [alt])

url 執行 [302] 重新導向。

字串「back」是特殊情況,用於提供 Referrer 支援,當 Referrer 不存在時,會使用 alt 或「/」。

ctx.redirect('back');
ctx.redirect('back', '/index.html');
ctx.redirect('/login');
ctx.redirect('http://google.com');

若要變更預設狀態 302,只需在此呼叫之前或之後指定狀態。若要變更主體,請在此呼叫之後指定。

ctx.status = 301;
ctx.redirect('/cart');
ctx.body = 'Redirecting to shopping cart';

response.attachment([filename], [options])

Content-Disposition 設定為「attachment」,以提示客戶端進行下載。選擇性地指定下載的 filename 和一些 選項

response.headerSent

檢查是否已傳送回應標頭。對於查看客戶端是否會在發生錯誤時收到通知很有用。

response.lastModified

如果存在,則傳回 Last-Modified 標頭作為 Date

response.lastModified=

設定 Last-Modified 標頭為適當的 UTC 字串。你可以將其設定為 Date 或日期字串。

ctx.response.lastModified = new Date();

response.etag=

設定回應的 ETag 包括包覆的 "。請注意,沒有對應的 response.etag getter。

ctx.response.etag = crypto.createHash('md5').update(ctx.body).digest('hex');

response.vary(field)

field 上變化。

response.flushHeaders()

清除任何設定的標頭,並開始主體。

贊助商

Apex Ping 是網站和 API 的美麗正常運行時間監控解決方案,由 Koa 的原始作者之一提供。

連結

社群連結,用於探索 Koa 的第三方中間件、完整的可執行範例、徹底的指南等等!如果你有任何問題,請在 IRC 中加入我們!