4.x API
express()
建立 Express 應用程式。express()
函式是 express
模組匯出的頂層函式。
var express = require('express')
var app = express()
方法
express.json([options])
此中間件在 Express v4.16.0 以上版本中提供。
這是 Express 中的內建中間件函式。它會剖析帶有 JSON 酬載的傳入要求,並根據 body-parser 建立。
傳回只剖析 JSON 且只查看 Content-Type
標頭與 type
選項相符的要求的中間件。此剖析器接受主體的任何 Unicode 編碼,並支援自動膨脹 gzip
和 deflate
編碼。
在中間件 (例如 req.body
) 之後,會在 request
物件上建立一個包含已剖析資料的新 body
物件,或是一個空物件 ({}
),如果沒有要剖析的內文、Content-Type
不相符,或發生錯誤。
由於 req.body
的形狀基於使用者控制的輸入,因此此物件中的所有屬性和值都不受信任,在信任之前應先驗證。例如,req.body.foo.toString()
可能會以多種方式失敗,例如 foo
可能不存在或不是字串,而 toString
可能不是函數,而是字串或其他使用者輸入。
下表說明選用 options
物件的屬性。
屬性 | 說明 | 類型 | 預設 |
---|---|---|---|
inflate |
啟用或停用處理已壓縮 (壓縮) 的內文;停用後,將拒絕已壓縮的內文。 | 布林值 | true |
limit |
控制最大要求內文大小。如果這是一個數字,則該值指定位元組數;如果它是一個字串,則該值會傳遞給 bytes 函式庫進行剖析。 | 混合 | "100kb" |
reviver |
reviver 選項會直接傳遞給 JSON.parse 作為第二個引數。您可以在 MDN 關於 JSON.parse 的文件 中找到有關此引數的更多資訊。 |
函數 | null |
strict |
啟用或停用僅接受陣列和物件;停用後,將接受 JSON.parse 接受的任何內容。 |
布林值 | true |
type |
這用於判斷中間件將解析哪種媒體類型。這個選項可以是字串、字串陣列或函式。如果非函式,type 選項會直接傳遞給 type-is 函式庫,這可以是副檔名(例如 json )、MIME 類型(例如 application/json )或帶有萬用字元的 MIME 類型(例如 */* 或 */json )。如果為函式,type 選項會呼叫為 fn(req) ,如果傳回真值,則會解析要求。 |
混合 | "application/json" |
驗證 |
如果提供這個選項,會呼叫為 verify(req, res, buf, encoding) ,其中 buf 是原始要求主體的 Buffer ,而 encoding 是要求的編碼。可以透過擲出錯誤來中止解析。 |
函數 | 未定義 |
express.raw([options])
這個中間件可在 Express v4.17.0 以上使用。
這是 Express 中內建的中間件函式。它會將輸入要求有效負載解析成 Buffer
,並根據 body-parser 執行。
傳回中間件,將所有主體解析成 Buffer
,並且只查看 Content-Type
標頭與 type
選項相符的要求。這個解析器接受主體的任何 Unicode 編碼,並支援自動膨脹 gzip
和 deflate
編碼。
在中間件(例如 req.body
)之後,會在 request
物件上填充一個包含已解析資料的新 body
Buffer
,或一個空物件({}
),如果沒有要解析的主體、Content-Type
不相符,或發生錯誤。
由於 req.body
的形狀是根據使用者控制的輸入,因此這個物件中的所有屬性和值都不受信任,在信任之前應該驗證。例如,req.body.toString()
可能會以多種方式失敗,例如堆疊多個解析器,req.body
可能來自不同的解析器。建議在呼叫緩衝區方法之前測試 req.body
是否為 Buffer
。
下表說明選用 options
物件的屬性。
屬性 | 說明 | 類型 | 預設 |
---|---|---|---|
inflate |
啟用或停用處理已壓縮 (壓縮) 的內文;停用後,將拒絕已壓縮的內文。 | 布林值 | true |
limit |
控制最大要求內文大小。如果這是一個數字,則該值指定位元組數;如果它是一個字串,則該值會傳遞給 bytes 函式庫進行剖析。 | 混合 | "100kb" |
type |
這用於判斷中間件將解析哪種類型的媒體。此選項可以是字串、字串陣列或函式。如果不是函式,type 選項會直接傳遞給 type-is 函式庫,這可以是副檔名 (例如 bin )、MIME 類型 (例如 application/octet-stream ) 或帶有萬用字元的 MIME 類型 (例如 */* 或 application/* )。如果是函式,type 選項會以 fn(req) 呼叫,如果傳回真值,則會解析請求。 |
混合 | "application/octet-stream" |
驗證 |
如果提供這個選項,會呼叫為 verify(req, res, buf, encoding) ,其中 buf 是原始要求主體的 Buffer ,而 encoding 是要求的編碼。可以透過擲出錯誤來中止解析。 |
函數 | 未定義 |
express.Router([options])
建立新的 路由器 物件。
var router = express.Router([options])
選用的 options
參數會指定路由器的行為。
屬性 | 說明 | 預設 | 可用性 |
---|---|---|---|
caseSensitive |
啟用大小寫敏感性。 | 預設為停用,將「/Foo」和「/foo」視為相同。 | |
mergeParams |
保留父路由器的 req.params 值。如果父路由器和子路由器有衝突的參數名稱,則子路由器的值優先。 |
false |
4.5.0+ |
strict |
啟用嚴格路由。 | 預設為停用,路由器會將「/foo」和「/foo/」視為相同。 |
您可以將中間件和 HTTP 方法路由 (例如 get
、put
、post
等) 新增到 router
,就像應用程式一樣。
如需更多資訊,請參閱 路由器。
express.static(root, [options])
這是 Express 中內建的中間件函式。它提供靜態檔案,並基於 serve-static。
注意:為了獲得最佳結果,使用反向代理快取 來提升提供靜態資源的效能。
root
參數指定用於提供靜態資源的根目錄。此函式會將 req.url
與提供的 root
目錄結合,來決定要提供的檔案。當找不到檔案時,它不會傳送 404 回應,而是呼叫 next()
以移至下一個中間軟體,允許堆疊和後備。
下表說明 options
物件的屬性。另請參閱 以下範例。
屬性 | 說明 | 類型 | 預設 |
---|---|---|---|
dotfiles |
決定如何處理點檔(以點「.」開頭的檔案或目錄)。 請參閱下方的 dotfiles。 |
字串 | 「忽略」 |
etag |
啟用或停用 etag 產生 注意: express.static 永遠會傳送弱 ETag。 |
布林值 | true |
extensions |
設定檔案副檔名後備:如果找不到檔案,請搜尋具有指定副檔名的檔案,並提供找到的第一個檔案。範例:['html', 'htm'] 。 |
混合 | false |
fallthrough |
讓用戶端錯誤作為未處理的請求,否則轉送用戶端錯誤。 請參閱下方的 fallthrough。 |
布林值 | true |
immutable |
在 Cache-Control 回應標頭中啟用或停用 immutable 指示。如果啟用,也應該指定 maxAge 選項以啟用快取。immutable 指示會防止支援的用戶端在 maxAge 選項的存續期間提出條件式請求,以檢查檔案是否已變更。 |
布林值 | false |
index |
傳送指定的目錄索引檔案。設定為 false 以停用目錄索引。 |
混合 | 「index.html」 |
lastModified |
將 Last-Modified 標頭設定為檔案在作業系統上的最後修改日期。 |
布林值 | true |
maxAge |
以毫秒或 ms 格式的字串設定 Cache-Control 標頭的 max-age 屬性。 | 數字 | 0 |
redirect |
當路徑名稱為目錄時,重新導向到尾端的「/」。 | 布林值 | true |
setHeaders |
用於設定 HTTP 標頭以與檔案一起提供的函式。 請參閱下方的 setHeaders。 |
函數 |
如需更多資訊,請參閱 在 Express 中提供靜態檔案 和 使用中間件 - 內建中間件。
dotfiles
此選項的可能值為
- 「allow」- 不對點檔進行特殊處理。
- 「deny」- 拒絕點檔的要求,回應
403
,然後呼叫next()
。 - 「ignore」- 行為就像點檔不存在一樣,回應
404
,然後呼叫next()
。
注意:使用預設值時,它不會忽略從點號開頭的目錄中的檔案。
fallthrough
當此選項為 true
時,用戶端錯誤(例如錯誤的要求或對不存在的檔案的要求)將導致此中間件僅呼叫 next()
以呼叫堆疊中的下一個中間件。為 false 時,這些錯誤(甚至是 404)將呼叫 next(err)
。
將此選項設定為 true
,這樣您就可以將多個實體目錄對應到同一個網路位址,或讓路由填入不存在的檔案。
如果您已將此中間件掛載在設計為嚴格單一檔案系統目錄的路徑上,請使用 false
,這允許短路 404 以減少負擔。此中間件也會回應所有方法。
setHeaders
對於此選項,請指定一個函式來設定自訂回應標頭。對標頭的變更必須同步發生。
函式的簽章為
fn(res, path, stat)
參數
res
,回應物件。path
,正在傳送的檔案路徑。stat
,正在傳送的檔案的stat
物件。
express.static 的範例
以下是使用 express.static
中間件函式並搭配精細選項物件的範例
var options = {
dotfiles: 'ignore',
etag: false,
extensions: ['htm', 'html'],
index: false,
maxAge: '1d',
redirect: false,
setHeaders: function (res, path, stat) {
res.set('x-timestamp', Date.now())
}
}
app.use(express.static('public', options))
express.text([選項])
這個中間件可在 Express v4.17.0 以上使用。
這是 Express 中的內建中間件函式。它會將輸入的請求有效負載解析成字串,並基於 body-parser。
傳回中間件,將所有主體解析為字串,且僅查看其中 Content-Type
標頭與 type
選項相符的請求。此剖析器接受主體的任何 Unicode 編碼,並支援自動膨脹 gzip
和 deflate
編碼。
在中間件 (即 req.body
) 之後,會在 request
物件上填充一個包含已解析資料的新 body
字串,或一個空物件 ({}
) (如果沒有要解析的主體、Content-Type
不相符,或發生錯誤)。
由於 req.body
的形狀基於使用者控制的輸入,因此此物件中的所有屬性和值都是不可信的,且在信任之前應先驗證。例如,req.body.trim()
可能以多種方式失敗,例如堆疊多個剖析器,req.body
可能來自不同的剖析器。建議在呼叫字串方法之前測試 req.body
是否為字串。
下表說明選用 options
物件的屬性。
屬性 | 說明 | 類型 | 預設 |
---|---|---|---|
defaultCharset |
如果請求的 Content-Type 標頭中未指定字元集,請指定文字內容的預設字元集。 |
字串 | "utf-8" |
inflate |
啟用或停用處理已壓縮 (壓縮) 的內文;停用後,將拒絕已壓縮的內文。 | 布林值 | true |
limit |
控制最大要求內文大小。如果這是一個數字,則該值指定位元組數;如果它是一個字串,則該值會傳遞給 bytes 函式庫進行剖析。 | 混合 | "100kb" |
type |
用於確定中間件將解析哪種類型的媒體。此選項可以是字串、字串陣列或函式。如果不是函式,則會將 type 選項直接傳遞給 type-is 函式庫,這可以是副檔名 (例如 txt )、MIME 類型 (例如 text/plain ) 或具有萬用字元的 MIME 類型 (例如 */* 或 text/* )。如果是函式,則會將 type 選項呼叫為 fn(req) ,如果傳回真值,則會解析請求。 |
混合 | "text/plain" |
驗證 |
如果提供這個選項,會呼叫為 verify(req, res, buf, encoding) ,其中 buf 是原始要求主體的 Buffer ,而 encoding 是要求的編碼。可以透過擲出錯誤來中止解析。 |
函數 | 未定義 |
express.urlencoded([options])
此中間件在 Express v4.16.0 以上版本中提供。
這是一個內建於 Express 的中間件函式。它會剖析帶有 URL 編碼載荷的傳入請求,並基於 body-parser。
傳回只會剖析 URL 編碼主體且只會查看 `Content-Type` 標頭與 `type` 選項相符的請求的中間件。此剖析器只接受主體的 UTF-8 編碼,並支援自動膨脹 `gzip` 和 `deflate` 編碼。
在中間件 (即 `req.body`) 之後,一個包含剖析資料的新 `body` 物件會填充在 `request` 物件上,或者如果沒有要剖析的主體、`Content-Type` 不相符或發生錯誤,則會填充一個空物件 ( `{}` )。此物件將包含鍵值對,其中值可以是字串或陣列 (當 `extended` 為 `false` 時),或任何類型 (當 `extended` 為 `true` 時)。
由於 req.body
的形狀基於使用者控制的輸入,因此此物件中的所有屬性和值都不受信任,在信任之前應先驗證。例如,req.body.foo.toString()
可能會以多種方式失敗,例如 foo
可能不存在或不是字串,而 toString
可能不是函數,而是字串或其他使用者輸入。
下表說明選用 options
物件的屬性。
屬性 | 說明 | 類型 | 預設 |
---|---|---|---|
extended |
此選項允許您選擇使用 `querystring` 函式庫 (當 `false` 時) 或 `qs` 函式庫 (當 `true` 時) 來剖析 URL 編碼資料。「extended」語法允許將豐富的物件和陣列編碼成 URL 編碼格式,讓 URL 編碼具有類似 JSON 的體驗。如需更多資訊,請 參閱 qs 函式庫。 | 布林值 | true |
inflate |
啟用或停用處理已壓縮 (壓縮) 的內文;停用後,將拒絕已壓縮的內文。 | 布林值 | true |
limit |
控制最大要求內文大小。如果這是一個數字,則該值指定位元組數;如果它是一個字串,則該值會傳遞給 bytes 函式庫進行剖析。 | 混合 | "100kb" |
parameterLimit |
此選項控制 URL 編碼資料中允許的最大參數數量。如果請求包含比此值更多的參數,則會引發錯誤。 | 數字 | 1000 |
type |
這用於決定中間件將解析什麼媒體類型。此選項可以是字串、字串陣列或函式。如果不是函式,type 選項會直接傳遞到 type-is 函式庫,這可以是副檔名(例如 urlencoded )、MIME 類型(例如 application/x-www-form-urlencoded )或具有萬用字元的 MIME 類型(例如 */x-www-form-urlencoded )。如果是函式,type 選項會以 fn(req) 的方式呼叫,如果傳回真值,則會解析請求。 |
混合 | "application/x-www-form-urlencoded" |
驗證 |
如果提供這個選項,會呼叫為 verify(req, res, buf, encoding) ,其中 buf 是原始要求主體的 Buffer ,而 encoding 是要求的編碼。可以透過擲出錯誤來中止解析。 |
函數 | 未定義 |
應用程式
app
物件慣例上表示 Express 應用程式。透過呼叫 Express 模組匯出的頂層 express()
函式來建立它
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('hello world')
})
app.listen(3000)
app
物件有下列方法
- HTTP 請求路由;例如,請參閱 app.METHOD 和 app.param。
- 設定中間件;請參閱 app.route。
- 呈現 HTML 檢視;請參閱 app.render。
- 註冊範本引擎;請參閱 app.engine。
它也有影響應用程式行為的設定(屬性);如需更多資訊,請參閱 應用程式設定。
屬性
app.locals
app.locals
物件有屬性,這些屬性是應用程式內的局部變數,而且會在使用 res.render 呈現的範本中提供。
locals
物件由檢視引擎用於呈現回應。物件金鑰可能特別敏感,不應包含使用者控制的輸入,因為它可能會影響檢視引擎的運作或提供跨網站指令碼的途徑。請諮詢所用檢視引擎的說明文件以取得其他考量因素。
console.dir(app.locals.title)
// => 'My App'
console.dir(app.locals.email)
// => 'me@myapp.com'
一旦設定,app.locals
屬性的值會持續存在於應用程式的生命週期中,這與僅在要求的生命週期中才有效的 res.locals 屬性形成對比。
您可以在應用程式內呈現的範本中存取區域變數。這對於提供範本的輔助函式以及應用程式層級資料非常有用。區域變數可透過 req.app.locals
在中間件中取得(請參閱 req.app)
app.locals.title = 'My App'
app.locals.strftime = require('strftime')
app.locals.email = 'me@myapp.com'
app.mountpath
app.mountpath
屬性包含一個或多個子應用程式已掛載的路徑模式。
子應用程式是 express
的執行個體,可用於處理對路由的要求。
var express = require('express')
var app = express() // the main app
var admin = express() // the sub app
admin.get('/', function (req, res) {
console.log(admin.mountpath) // /admin
res.send('Admin Homepage')
})
app.use('/admin', admin) // mount the sub app
它類似於 req
物件的 baseUrl 屬性,不同之處在於 req.baseUrl
會傳回已配對的 URL 路徑,而不是已配對的模式。
如果子應用程式掛載在多個路徑模式上,app.mountpath
會傳回已掛載模式的清單,如下列範例所示。
var admin = express()
admin.get('/', function (req, res) {
console.dir(admin.mountpath) // [ '/adm*n', '/manager' ]
res.send('Admin Homepage')
})
var secret = express()
secret.get('/', function (req, res) {
console.log(secret.mountpath) // /secr*t
res.send('Admin Secret')
})
admin.use('/secr*t', secret) // load the 'secret' router on '/secr*t', on the 'admin' sub app
app.use(['/adm*n', '/manager'], admin) // load the 'admin' router on '/adm*n' and '/manager', on the parent app
事件
app.on('mount', callback(parent))
當子應用程式掛載在父應用程式上時,會觸發 mount
事件。父應用程式會傳遞給 callback 函式。
var admin = express()
admin.on('mount', function (parent) {
console.log('Admin Mounted')
console.log(parent) // refers to the parent app
})
admin.get('/', function (req, res) {
res.send('Admin Homepage')
})
app.use('/admin', admin)
方法
app.all(path, callback [, callback ...])
此方法類似於標準的 app.METHOD() 方法,但它會配對所有 HTTP 動詞。
參數
引數 | 說明 | 預設 |
---|---|---|
path |
呼叫中間件函式的路徑;可以是下列任一項
|
'/'(根路徑) |
回呼 |
回呼函式;可以是
您可以提供多個回呼函式,其行為就像中間件,但這些回呼函式可以呼叫 由於 路由器 和 應用程式 實作中間件介面,因此您可以像使用任何其他中間件函式一樣使用它們。 範例請參閱 中間件回呼函式範例。 |
無 |
範例
以下回呼函式會在對 /secret
提出要求時執行,無論是使用 GET、POST、PUT、DELETE 或任何其他 HTTP 要求方法
app.all('/secret', function (req, res, next) {
console.log('Accessing the secret section ...')
next() // pass control to the next handler
})
app.all()
方法對於對特定路徑前綴或任意比對設定「全域」邏輯非常有用。例如,如果您將以下內容置於所有其他路由定義的最上方,則表示從該點開始的所有路由都需要驗證,並自動載入使用者。請記住,這些回呼函式不必充當終端點:loadUser
可以執行某項任務,然後呼叫 next()
以繼續比對後續路由。
app.all('*', requireAuthentication, loadUser)
或等效的
app.all('*', requireAuthentication)
app.all('*', loadUser)
另一個範例是白名單的「全域」功能。此範例類似於上述範例,但它只限制從「/api」開始的路徑
app.all('/api/*', requireAuthentication)
app.delete(path, callback [, callback ...])
將 HTTP DELETE 要求路由到指定的路徑,並使用指定的回呼函式。如需更多資訊,請參閱 路由指南。
參數
引數 | 說明 | 預設 |
---|---|---|
path |
呼叫中間件函式的路徑;可以是下列任一項
|
'/'(根路徑) |
回呼 |
回呼函式;可以是
您可以提供多個回呼函式,其行為就像中間件,但這些回呼函式可以呼叫 由於 路由器 和 應用程式 實作中間件介面,因此您可以像使用任何其他中間件函式一樣使用它們。 範例請參閱 中間件回呼函式範例。 |
無 |
範例
app.delete('/', function (req, res) {
res.send('DELETE request to homepage')
})
app.disable(name)
將布林設定 name
設為 false
,其中 name
是 app 設定表 中的其中一個屬性。針對布林屬性呼叫 app.set('foo', false)
與呼叫 app.disable('foo')
相同。
例如
app.disable('trust proxy')
app.get('trust proxy')
// => false
app.disabled(name)
如果布林設定 name
已停用 (false
),則傳回 true
,其中 name
是 app 設定表 中的其中一個屬性。
app.disabled('trust proxy')
// => true
app.enable('trust proxy')
app.disabled('trust proxy')
// => false
app.enable(name)
將布林設定 name
設為 true
,其中 name
是 app 設定表 中的其中一個屬性。針對布林屬性呼叫 app.set('foo', true)
與呼叫 app.enable('foo')
相同。
app.enable('trust proxy')
app.get('trust proxy')
// => true
app.enabled(name)
如果設定 name
已啟用 (true
),則傳回 true
,其中 name
是 app 設定表 中的其中一個屬性。
app.enabled('trust proxy')
// => false
app.enable('trust proxy')
app.enabled('trust proxy')
// => true
app.engine(ext, callback)
將指定的範本引擎 callback
註冊為 ext
。
預設情況下,Express 會根據檔案副檔名 require()
引擎。例如,如果您嘗試呈現「foo.pug」檔案,Express 會在內部呼叫下列內容,並在後續呼叫中快取 require()
以提升效能。
app.engine('pug', require('pug').__express)
針對未提供現成的 .__express
的引擎,或如果您希望將不同的副檔名「對應」到範本引擎,請使用此方法。
例如,將 EJS 範本引擎對應到「.html」檔案
app.engine('html', require('ejs').renderFile)
在這種情況下,EJS 提供一個 .renderFile()
方法,其簽章與 Express 預期的相同:(path, options, callback)
,但請注意,它在內部將此方法別名為 ejs.__express
,因此如果您使用「.ejs」副檔名,則無需執行任何操作。
有些範本引擎不遵循此慣例。consolidate.js 函式庫將 Node 範本引擎對應到遵循此慣例,因此它們可以與 Express 無縫運作。
var engines = require('consolidate')
app.engine('haml', engines.haml)
app.engine('html', engines.hogan)
app.get(name)
傳回 name
應用程式設定的值,其中 name
是 應用程式設定表格 中的字串之一。例如
app.get('title')
// => undefined
app.set('title', 'My Site')
app.get('title')
// => "My Site"
app.get(path, callback [, callback ...])
將 HTTP GET 要求路由到指定的路徑,並使用指定的回呼函式。
參數
引數 | 說明 | 預設 |
---|---|---|
path |
呼叫中間件函式的路徑;可以是下列任一項
|
'/'(根路徑) |
回呼 |
回呼函式;可以是
您可以提供多個回呼函式,其行為就像中間件,但這些回呼函式可以呼叫 由於 路由器 和 應用程式 實作中間件介面,因此您可以像使用任何其他中間件函式一樣使用它們。 範例請參閱 中間件回呼函式範例。 |
無 |
如需更多資訊,請參閱 路由指南。
範例
app.get('/', function (req, res) {
res.send('GET request to homepage')
})
app.listen(path, [callback])
啟動 UNIX socket,並在指定的 path 上聆聽連線。此方法與 Node 的 http.Server.listen() 相同。
var express = require('express')
var app = express()
app.listen('/tmp/sock')
app.listen([port[, host[, backlog]]][, callback])
繫結並在指定的 host 和 port 上聆聽連線。此方法與 Node 的 http.Server.listen() 相同。
如果省略 port 或 port 為 0,作業系統會指派一個任意未使用的 port,這對於自動化工作(測試等)很有用。
var express = require('express')
var app = express()
app.listen(3000)
express()
傳回的 app
實際上是 JavaScript Function
,設計為傳遞給 Node 的 HTTP 伺服器,作為處理要求的回呼。這使得您可以使用相同的程式碼庫輕鬆提供 HTTP 和 HTTPS 版本的應用程式,因為應用程式不會繼承這些(它只是一個回呼)。
var express = require('express')
var https = require('https')
var http = require('http')
var app = express()
http.createServer(app).listen(80)
https.createServer(options, app).listen(443)
app.listen()
方法傳回一個 http.Server 物件,並且(對於 HTTP)是下列項目的簡便方法
app.listen = function () {
var server = http.createServer(this)
return server.listen.apply(server, arguments)
}
注意:Node 的 http.Server.listen() 方法的所有形式實際上都受到支援。
app.METHOD(path, callback [, callback ...])
路由 HTTP 要求,其中 METHOD 是要求的 HTTP 方法,例如 GET、PUT、POST 等,以小寫字母表示。因此,實際的方法是 app.get()
、app.post()
、app.put()
等。請參閱下方的 路由方法 以取得完整清單。
參數
引數 | 說明 | 預設 |
---|---|---|
path |
呼叫中間件函式的路徑;可以是下列任一項
|
'/'(根路徑) |
回呼 |
回呼函式;可以是
您可以提供多個回呼函式,其行為就像中間件,但這些回呼函式可以呼叫 由於 路由器 和 應用程式 實作中間件介面,因此您可以像使用任何其他中間件函式一樣使用它們。 範例請參閱 中間件回呼函式範例。 |
無 |
路由方法
Express 支援以下路由方法,對應於同名的 HTTP 方法
|
|
|
API 文件僅針對最受歡迎的 HTTP 方法 app.get()
、app.post()
、app.put()
和 app.delete()
有明確的項目。不過,上面列出的其他方法的工作方式完全相同。
要路由轉換為無效 JavaScript 變數名稱的方法,請使用方括號表示法。例如,app['m-search']('/', function ...
。
如果在 app.get()
之前未針對路徑呼叫 app.head()
,則會自動針對 GET
方法以外的 HTTP HEAD
方法呼叫 app.get()
函數。
方法 app.all()
沒有衍生自任何 HTTP 方法,而且會針對 所有 HTTP 要求方法載入指定路徑的 middleware。如需更多資訊,請參閱 app.all。
如需有關路由的更多資訊,請參閱 路由指南。
app.param([name], callback)
將回呼觸發器新增到路由參數,其中 name
是參數的名稱或陣列,而 callback
是回呼函式。回呼函式的參數為請求物件、回應物件、下一個中間軟體、參數值和參數名稱,順序依此類推。
如果 name
是陣列,則 callback
觸發器會為其中宣告的每個參數註冊,順序依宣告順序。此外,對於除最後一個以外的每個宣告參數,在回呼中呼叫 next
將會呼叫下一個宣告參數的回呼。對於最後一個參數,呼叫 next
將會呼叫目前正在處理的路由的下一中間軟體,就像 name
僅為字串一樣。
例如,當路由路徑中出現 :user
時,你可以對應使用者載入邏輯,以自動將 req.user
提供給路由,或對參數輸入執行驗證。
app.param('user', function (req, res, next, id) {
// try to get the user details from the User model and attach it to the request object
User.find(id, function (err, user) {
if (err) {
next(err)
} else if (user) {
req.user = user
next()
} else {
next(new Error('failed to load user'))
}
})
})
參數回呼函式是定義它們的路由器的區域性函式。它們不會被掛載的應用程式或路由器繼承。因此,定義在 app
上的參數回呼只會由定義在 app
路由上的路由參數觸發。
所有參數回呼都將在參數出現的任何路由的任何處理常式之前呼叫,而且它們在請求-回應週期中只會被呼叫一次,即使參數在多個路由中比對成功,如下列範例所示。
app.param('id', function (req, res, next, id) {
console.log('CALLED ONLY ONCE')
next()
})
app.get('/user/:id', function (req, res, next) {
console.log('although this matches')
next()
})
app.get('/user/:id', function (req, res) {
console.log('and this matches too')
res.end()
})
在 GET /user/42
中,會列印下列內容
CALLED ONLY ONCE
although this matches
and this matches too
app.param(['id', 'page'], function (req, res, next, value) {
console.log('CALLED ONLY ONCE with', value)
next()
})
app.get('/user/:id/:page', function (req, res, next) {
console.log('although this matches')
next()
})
app.get('/user/:id/:page', function (req, res) {
console.log('and this matches too')
res.end()
})
在 GET /user/42/3
中,會列印下列內容
CALLED ONLY ONCE with 42
CALLED ONLY ONCE with 3
although this matches
and this matches too
下列區段說明 app.param(callback)
,它已在 v4.11.0 中標示為不建議使用。
app.param(name, callback)
方法的行為可以透過僅傳遞一個函式給 app.param()
來完全變更。這個函式是 app.param(name, callback)
應如何運作的客製化實作 - 它接受兩個參數,且必須回傳一個中間軟體。
此函數的第一個參數是要擷取的 URL 參數名稱,第二個參數可以是任何 JavaScript 物件,可用於傳回中間件實作。
函數傳回的中間件決定擷取 URL 參數時會發生什麼事。
在此範例中,app.param(name, callback)
簽章已修改為 app.param(name, accessId)
。app.param()
現在會接受名稱和數字,而不是名稱和回呼。
var express = require('express')
var app = express()
// customizing the behavior of app.param()
app.param(function (param, option) {
return function (req, res, next, val) {
if (val === option) {
next()
} else {
next('route')
}
}
})
// using the customized app.param()
app.param('id', 1337)
// route to trigger the capture
app.get('/user/:id', function (req, res) {
res.send('OK')
})
app.listen(3000, function () {
console.log('Ready')
})
在此範例中,app.param(name, callback)
簽章保持不變,但已定義自訂資料類型檢查函數來驗證使用者 ID 的資料類型,而不是中間件回呼。
app.param(function (param, validator) {
return function (req, res, next, val) {
if (validator(val)) {
next()
} else {
next('route')
}
}
})
app.param('id', function (candidate) {
return !isNaN(parseFloat(candidate)) && isFinite(candidate)
})
「.
」字元無法用於在擷取正規表示法中擷取字元。例如,您無法使用 '/user-.+/'
擷取 'users-gami'
,請改用 [\\s\\S]
或 [\\w\\W]
(例如 '/user-[\\s\\S]+/'
)。
範例
// captures '1-a_6' but not '543-azser-sder'
router.get('/[0-9]+-[[\\w]]*', function (req, res, next) { next() })
// captures '1-a_6' and '543-az(ser"-sder' but not '5-a s'
router.get('/[0-9]+-[[\\S]]*', function (req, res, next) { next() })
// captures all (equivalent to '.*')
router.get('[[\\s\\S]]*', function (req, res, next) { next() })
app.path()
傳回應用程式的正規路徑(字串)。
var app = express()
var blog = express()
var blogAdmin = express()
app.use('/blog', blog)
blog.use('/admin', blogAdmin)
console.dir(app.path()) // ''
console.dir(blog.path()) // '/blog'
console.dir(blogAdmin.path()) // '/blog/admin'
此方法的行為在複雜的已掛載應用程式案例中可能會變得非常複雜:通常最好使用 req.baseUrl 來取得應用程式的正規路徑。
app.post(path, callback [, callback ...])
將 HTTP POST 要求路由到指定路徑,並使用指定的回呼函數。如需更多資訊,請參閱 路由指南。
參數
引數 | 說明 | 預設 |
---|---|---|
path |
呼叫中間件函式的路徑;可以是下列任一項
|
'/'(根路徑) |
回呼 |
回呼函式;可以是
您可以提供多個回呼函式,其行為就像中間件,但這些回呼函式可以呼叫 由於 路由器 和 應用程式 實作中間件介面,因此您可以像使用任何其他中間件函式一樣使用它們。 範例請參閱 中間件回呼函式範例。 |
無 |
範例
app.post('/', function (req, res) {
res.send('POST request to homepage')
})
app.put(path, callback [, callback ...])
將 HTTP PUT 要求路由到指定路徑,並使用指定的回呼函數。
參數
引數 | 說明 | 預設 |
---|---|---|
path |
呼叫中間件函式的路徑;可以是下列任一項
|
'/'(根路徑) |
回呼 |
回呼函式;可以是
您可以提供多個回呼函式,其行為就像中間件,但這些回呼函式可以呼叫 由於 路由器 和 應用程式 實作中間件介面,因此您可以像使用任何其他中間件函式一樣使用它們。 範例請參閱 中間件回呼函式範例。 |
無 |
範例
app.put('/', function (req, res) {
res.send('PUT request to homepage')
})
app.render(view, [locals], callback)
透過 callback
函數傳回檢視的已呈現 HTML。它接受一個選用參數,該參數是包含檢視的區域變數的物件。它就像 res.render(),但它無法自行將已呈現的檢視傳送給客戶端。
將 app.render()
視為用於產生已呈現檢視字串的公用函數。在內部,res.render()
使用 app.render()
來呈現檢視。
view
參數執行檔案系統操作,例如從磁碟讀取檔案和評估 Node.js 模組,因此出於安全原因,不應包含來自最終使用者的輸入。
locals
物件由檢視引擎用於呈現回應。物件金鑰可能特別敏感,不應包含使用者控制的輸入,因為它可能會影響檢視引擎的運作或提供跨網站指令碼的途徑。請諮詢所用檢視引擎的說明文件以取得其他考量因素。
保留區域變數 cache
以啟用檢視快取。如果您要在開發期間快取檢視,請將其設定為 true
;預設會在製作環境中啟用檢視快取。
app.render('email', function (err, html) {
// ...
})
app.render('email', { name: 'Tobi' }, function (err, html) {
// ...
})
app.route(path)
傳回單一路由的執行個體,然後您可以使用它來處理 HTTP 動詞(搭配可選的 middleware)。使用 app.route()
以避免重複的路由名稱(以及因此產生的拼字錯誤)。
var app = express()
app.route('/events')
.all(function (req, res, next) {
// runs for all HTTP verbs first
// think of it as route specific middleware!
})
.get(function (req, res, next) {
res.json({})
})
.post(function (req, res, next) {
// maybe add a new event...
})
app.set(name, value)
將設定 name
指定給 value
。您可以儲存您想要的任何值,但某些名稱可用於設定伺服器的行為。這些特殊名稱列於 應用程式設定表格 中。
對於布林屬性,呼叫 app.set('foo', true)
等同於呼叫 app.enable('foo')
。類似地,對於布林屬性,呼叫 app.set('foo', false)
等同於呼叫 app.disable('foo')
。
使用 app.get()
擷取設定的值。
app.set('title', 'My Site')
app.get('title') // "My Site"
應用程式設定
下表列出應用程式設定。
請注意,子應用程式將
- 不繼承具有預設值的設定值。您必須在子應用程式中設定值。
- 繼承沒有預設值的設定值;這些值會在下表中明確註明。
例外:子應用程式將繼承 trust proxy
的值,即使它有預設值(為了向後相容性);子應用程式不會在製作環境中繼承 view cache
的值(當 NODE_ENV
為「製作環境」時)。
屬性 | 類型 | 說明 | 預設 |
---|---|---|---|
|
布林值 | 啟用大小寫敏感性。啟用後,「/Foo」和「/foo」是不同的路由。停用後,「/Foo」和「/foo」會被視為相同。 注意:子應用程式會繼承此設定的值。 |
N/A(未定義) |
|
字串 | 環境模式。請務必在生產環境中設定為「生產」;請參閱生產最佳實務:效能和可靠性。 |
|
|
變數 |
設定 ETag 回應標頭。有關可能的數值,請參閱 |
|
|
字串 | 指定預設 JSONP 回呼名稱。 |
“callback” |
|
布林值 |
啟用從 注意:子應用程式會繼承此設定的值。 |
N/A(未定義) |
|
變數 | `JSON.stringify` 使用的「replacer」參數。
注意:子應用程式會繼承此設定的值。 |
N/A(未定義) |
|
變數 | `JSON.stringify` 使用的「space」參數。這通常設定為用於縮排美化 JSON 的空格數。
注意:子應用程式會繼承此設定的值。 |
N/A(未定義) |
|
變數 |
透過將值設定為 簡單的查詢解析器基於 Node 的原生查詢解析器,querystring。 擴充查詢解析器基於 qs。 自訂的查詢字串解析函式會收到完整的查詢字串,並必須傳回查詢金鑰及其值的物件。 |
"擴充" |
|
布林值 | 啟用嚴格路由。啟用後,路由器會將「/foo」和「/foo/」視為不同的路徑。否則,路由器會將「/foo」和「/foo/」視為相同的路徑。 注意:子應用程式會繼承此設定的值。 |
N/A(未定義) |
|
數字 | 要移除以存取次網域的主機的點分隔部分數目。 | 2 |
|
變數 |
表示應用程式位於面對面的代理伺服器之後,並使用 啟用後,Express 會嘗試判斷透過面對面的代理伺服器或一系列代理伺服器連線的用戶端的 IP 位址。然後,`req.ips` 屬性會包含用戶端連線的 IP 位址陣列。若要啟用,請使用 信任代理伺服器選項表格 中所述的值。 `trust proxy` 設定是使用 proxy-addr 套件實作的。如需更多資訊,請參閱其文件。 注意:子應用程式會繼承此設定的值,即使它有預設值。 |
|
|
字串或陣列 | 應用程式檢視的目錄或目錄陣列。如果是陣列,檢視會按其在陣列中出現的順序查詢。 |
|
|
布林值 | 啟用檢視範本編譯快取。 注意:子應用程式在生產環境(當 `NODE_ENV` 為「production」)中不會繼承此設定的值。 |
在生產環境中為 |
|
字串 | 省略時要使用的預設引擎擴充功能。
注意:子應用程式會繼承此設定的值。 |
N/A(未定義) |
|
布林值 | 啟用「X-Powered-By: Express」HTTP 標頭。 |
|
`trust proxy` 設定的選項
請閱讀 Express 背後的代理伺服器 以取得更多資訊。
類型 | 值 |
---|---|
布林值 |
如果為 如果為 |
字串 包含逗號分隔值的字串 字串陣列 |
要信任的 IP 位址、子網路或 IP 位址和子網路陣列。預先設定的子網路名稱為
使用下列任何一種方式設定 IP 位址 指定單一子網路
指定子網路和位址
以 CSV 指定多個子網路
以陣列指定多個子網路
指定時,IP 位址或子網路會從位址判斷過程中排除,且最接近應用程式伺服器的非信任 IP 位址會判斷為客戶端的 IP 位址。 |
數字 |
信任來自面向前端代理伺服器的第 n 個跳轉作為客戶端。 |
函數 |
自訂信任實作。只有在您知道自己在做什麼時才使用此選項。
|
`etag` 設定的選項
注意:這些設定僅適用於動態檔案,不適用於靜態檔案。 express.static 中介軟體會忽略這些設定。
ETag 功能是使用 etag 套件實作的。如需更多資訊,請參閱其文件。
類型 | 值 |
---|---|
布林值 |
|
字串 |
如果為「strong」,會啟用強 ETag。 如果為「weak」,會啟用弱 ETag。 |
函數 |
自訂 ETag 函式實作。只有在知道自己在做什麼時才使用這個。
|
app.use([路徑,] 回呼 [, 回呼...])
掛載指定 中間件 函式或函式到指定路徑:當請求路徑的基礎與 路徑
相符時,會執行中間件函式。
參數
引數 | 說明 | 預設 |
---|---|---|
path |
呼叫中間件函式的路徑;可以是下列任一項
|
'/'(根路徑) |
回呼 |
回呼函式;可以是
您可以提供多個回呼函式,其行為就像中間件,但這些回呼函式可以呼叫 由於 路由器 和 應用程式 實作中間件介面,因此您可以像使用任何其他中間件函式一樣使用它們。 範例請參閱 中間件回呼函式範例。 |
無 |
說明
路由會與在它的路徑後緊接「/
」的任何路徑相符。例如:app.use('/apple', ...)
會與「/apple」、「/apple/images」、「/apple/images/news」等相符。
由於 路徑
預設為「/」,未指定路徑而掛載的中間件會對應用程式中的每個請求執行。
例如,這個中間件函式會對應用程式中的每個請求執行
app.use(function (req, res, next) {
console.log('Time: %d', Date.now())
next()
})
中間件函式會依序執行,因此中間件包含的順序很重要。
// this middleware will not allow the request to go beyond it
app.use(function (req, res, next) {
res.send('Hello World')
})
// requests will never reach this route
app.get('/', function (req, res) {
res.send('Welcome')
})
錯誤處理中間件
錯誤處理中間件總是需要四個參數。你必須提供四個參數來辨識它為錯誤處理中間件函式。即使你不需要使用 next
物件,你仍必須指定它來維護簽章。否則,next
物件會被解譯為一般中間件,而無法處理錯誤。有關錯誤處理中間件的詳細資訊,請參閱:錯誤處理。
定義錯誤處理中間件函式的步驟與其他中間件函式相同,但參數有四個而不是三個,特別是簽章為 (err, req, res, next)
)
app.use(function (err, req, res, next) {
console.error(err.stack)
res.status(500).send('Something broke!')
})
路徑範例
下表提供一些用於掛載中間件的有效 路徑
值的簡單範例。
類型 | 範例 |
---|---|
路徑 |
這會與從
|
路徑模式 |
這會與從
這會比對以
這會比對以
這會比對以
|
正規表示法 |
這會比對以
|
陣列 |
這會比對以
|
中間件回呼函數範例
下表提供一些中間件函數的簡單範例,這些函數可用作 app.use()
、app.METHOD()
和 app.all()
的 callback
參數。即使範例是針對 app.use()
,但它們也適用於 app.use()
、app.METHOD()
和 app.all()
。
用法 | 範例 |
---|---|
單一中間件 |
您可以在本地定義並掛載中間件函數。
路由器是有效的中間件。
Express 應用程式是有效的中間件。
|
中間件系列 |
您可以在同一個掛載路徑上指定多個中間件函數。
|
陣列 |
使用陣列以邏輯方式分組中間件。
|
組合 |
您可以結合上述所有方式來掛載中間件。
|
以下是使用 Express 應用程式中的 express.static 中間件的一些範例。
從應用程式目錄中的「public」目錄為應用程式提供靜態內容
// GET /style.css etc
app.use(express.static(path.join(__dirname, 'public')))
在「/static」處掛載中間件,僅在請求路徑加上「/static」前綴時提供靜態內容
// GET /static/style.css etc.
app.use('/static', express.static(path.join(__dirname, 'public')))
在靜態中間件之後載入記錄器中間件,以停用靜態內容請求的記錄
app.use(express.static(path.join(__dirname, 'public')))
app.use(logger())
從多個目錄提供靜態檔案,但優先使用「./public」
app.use(express.static(path.join(__dirname, 'public')))
app.use(express.static(path.join(__dirname, 'files')))
app.use(express.static(path.join(__dirname, 'uploads')))
要求
req
物件代表 HTTP 要求,並具有要求查詢字串、參數、主體、HTTP 標頭等屬性。在此文件中,依慣例,物件總是稱為 req
(HTTP 回應為 res
),但其實際名稱由您正在使用的回呼函式的參數決定。
例如
app.get('/user/:id', function (req, res) {
res.send('user ' + req.params.id)
})
但您也可以使用
app.get('/user/:id', function (request, response) {
response.send('user ' + request.params.id)
})
req
物件是 Node 自身要求物件的加強版本,並支援所有 內建欄位和方法。
屬性
在 Express 4 中,req.files
預設不再在 req
物件中提供。若要存取 req.files
物件中的上傳檔案,請使用多部分處理中介軟體,例如 busboy、multer、formidable、multiparty、connect-multiparty 或 pez。
req.app
此屬性持有正在使用中介軟體的 Express 應用程式實例的參考。
如果您遵循在其中建立僅匯出中介軟體函式的模組並在主檔案中 require()
的模式,則中介軟體可透過 req.app
存取 Express 實例。
例如
// index.js
app.get('/viewdirectory', require('./mymiddleware.js'))
// mymiddleware.js
module.exports = function (req, res) {
res.send('The views directory is ' + req.app.get('views'))
}
req.baseUrl
已掛載路由器實例的 URL 路徑。
req.baseUrl
屬性類似於 app
物件的 mountpath 屬性,但 app.mountpath
會傳回已配對的路徑模式。
例如
var greet = express.Router()
greet.get('/jp', function (req, res) {
console.log(req.baseUrl) // /greet
res.send('Konichiwa!')
})
app.use('/greet', greet) // load the router on '/greet'
即使您使用路徑模式或一組路徑模式來載入路由器,baseUrl
屬性仍會傳回已配對的字串,而不是模式。在以下範例中,greet
路由器載入在兩個路徑模式上。
app.use(['/gre+t', '/hel{2}o'], greet) // load the router on '/gre+t' and '/hel{2}o'
當對 /greet/jp
提出要求時,req.baseUrl
為 “/greet”。當對 /hello/jp
提出要求時,req.baseUrl
為 “/hello”。
req.body
包含請求主體中提交的鍵值資料對。預設為 undefined
,當您使用主體解析中介軟體(例如 express.json()
或 express.urlencoded()
)時會填入資料。
由於 req.body
的形狀基於使用者控制的輸入,因此此物件中的所有屬性和值都不受信任,在信任之前應先驗證。例如,req.body.foo.toString()
可能會以多種方式失敗,例如 foo
可能不存在或不是字串,而 toString
可能不是函數,而是字串或其他使用者輸入。
下列範例顯示如何使用主體解析中介軟體填入 req.body
。
var express = require('express')
var app = express()
app.use(express.json()) // for parsing application/json
app.use(express.urlencoded({ extended: true })) // for parsing application/x-www-form-urlencoded
app.post('/profile', function (req, res, next) {
console.log(req.body)
res.json(req.body)
})
req.cookies
使用 cookie-parser 中介軟體時,此屬性為包含請求傳送的 cookie 的物件。如果請求不包含 cookie,預設為 {}
。
// Cookie: name=tj
console.dir(req.cookies.name)
// => 'tj'
如果 cookie 已簽署,您必須使用 req.signedCookies。
如需更多資訊、問題或疑慮,請參閱 cookie-parser。
req.fresh
當回應在客戶端快取中仍為「新鮮」時,會傳回 true
,否則會傳回 false
以表示客戶端快取現在已過期,且應傳送完整回應。
當客戶端傳送 Cache-Control: no-cache
請求標頭以表示端對端重新載入請求時,此模組會傳回 false
以透明地處理這些請求。
有關快取驗證運作方式的更多詳細資料,請參閱 HTTP/1.1 快取規格。
console.dir(req.fresh)
// => true
req.hostname
包含從 Host
HTTP 標頭衍生的主機名稱。
當 信任代理
設定 未評估為 false
時,此屬性將改為從 X-Forwarded-Host
標頭欄位取得值。此標頭可以由客戶端或代理程式設定。
如果請求中有多個 X-Forwarded-Host
標頭,則使用第一個標頭的值。這包括一個帶有逗號分隔值的單一標頭,其中使用第一個值。
在 Express v4.17.0 之前,X-Forwarded-Host
不能包含多個值或不能出現多次。
// Host: "example.com:3000"
console.dir(req.hostname)
// => 'example.com'
req.ip
包含請求的遠端 IP 位址。
當 trust proxy
設定 未評估為 false
時,此屬性的值來自 X-Forwarded-For
標頭中最左邊的項目。此標頭可以由客戶端或代理程式設定。
console.dir(req.ip)
// => '127.0.0.1'
req.ips
當 trust proxy
設定 未評估為 false
時,此屬性包含在 X-Forwarded-For
請求標頭中指定的 IP 位址陣列。否則,它包含一個空陣列。此標頭可以由客戶端或代理程式設定。
例如,如果 X-Forwarded-For
是 client, proxy1, proxy2
,則 req.ips
會是 ["client", "proxy1", "proxy2"]
,其中 proxy2
是最下游的。
req.method
包含與請求的 HTTP 方法對應的字串:GET
、POST
、PUT
等。
req.originalUrl
req.url
不是原生 Express 屬性,它繼承自 Node 的 http 模組。
此屬性與 req.url
非常類似;但是,它會保留原始請求 URL,讓您能自由改寫 req.url
以供內部路由使用。例如,app.use() 的「掛載」功能會改寫 req.url
以移除掛載點。
// GET /search?q=something
console.dir(req.originalUrl)
// => '/search?q=something'
req.originalUrl
可同時在中間件和路由物件中使用,且是 req.baseUrl
和 req.url
的組合。請考慮以下範例
app.use('/admin', function (req, res, next) { // GET 'http://www.example.com/admin/new?sort=desc'
console.dir(req.originalUrl) // '/admin/new?sort=desc'
console.dir(req.baseUrl) // '/admin'
console.dir(req.path) // '/new'
next()
})
req.params
此屬性是一個物件,其中包含對應到 命名路由「參數」 的屬性。例如,如果您有路由 /user/:name
,則「name」屬性可用作 req.params.name
。此物件預設為 {}
。
// GET /user/tj
console.dir(req.params.name)
// => 'tj'
當您對路由定義使用正規表示式時,會在陣列中提供擷取群組,使用 req.params[n]
,其中 n
是第 n
個擷取群組。此規則套用於使用字串路由的未命名萬用字元比對,例如 /file/*
// GET /file/javascripts/jquery.js
console.dir(req.params[0])
// => 'javascripts/jquery.js'
如果您需要變更 req.params
中的某個金鑰,請使用 app.param 處理常式。變更僅適用於已在路由路徑中定義的 參數。
在中間件或路由處理常式中對 req.params
物件所做的任何變更都會重設。
注意:Express 會自動解碼 req.params
中的值(使用 decodeURIComponent
)。
req.path
包含請求 URL 的路徑部分。
// example.com/users?sort=desc
console.dir(req.path)
// => '/users'
從中間件呼叫時,掛載點不會包含在 req.path
中。請參閱 app.use() 以取得更多詳細資料。
req.protocol
包含請求協定字串:http
或(對於 TLS 請求)https
。
當 trust proxy
設定 的評估結果不為 false
時,此屬性會使用 X-Forwarded-Proto
標頭欄位的數值(如果存在)。此標頭可以由用戶端或代理程式設定。
console.dir(req.protocol)
// => 'http'
req.query
此屬性是一個物件,其中包含路由中每個查詢字串參數的屬性。當 查詢解析器 設定為停用時,它會是一個空的物件 {}
,否則它會是已設定查詢解析器的結果。
由於 req.query
的形狀是根據使用者控制的輸入,此物件中的所有屬性和值都是不可信的,在信任之前應先驗證。例如,req.query.foo.toString()
可能會以多種方式失敗,例如 foo
可能不存在或不是字串,而 toString
可能不是函式,而是字串或其他使用者輸入。
此屬性的值可以使用 查詢剖析器應用程式設定 進行設定,以符合應用程式的需求。一個非常流行的查詢字串剖析器是 qs
模組,這是預設使用的。qs
模組具有許多設定,可以進行非常多的設定,而且可能需要使用與預設值不同的設定來填入 req.query
var qs = require('qs')
app.set('query parser', function (str) {
return qs.parse(str, { /* custom options */ })
})
查看 查詢剖析器應用程式設定 文件,以取得其他自訂選項。
req.res
此屬性保留對應於此請求物件的 回應物件 的參考。
req.route
包含目前配對的路由,是一個字串。例如
app.get('/user/:id?', function userIdHandler (req, res) {
console.log(req.route)
res.send('GET')
})
前一個程式片段的範例輸出
{ path: '/user/:id?',
stack:
[ { handle: [Function: userIdHandler],
name: 'userIdHandler',
params: undefined,
path: undefined,
keys: [],
regexp: /^\/?$/i,
method: 'get' } ],
methods: { get: true } }
req.secure
如果建立 TLS 連線,則為 true 的布林屬性。等同於
console.dir(req.protocol === 'https')
// => true
req.signedCookies
使用 cookie-parser 中介軟體時,此屬性包含請求傳送的已簽署 cookie,未簽署且已準備好使用。已簽署的 cookie 位於不同的物件中,以顯示開發人員的意圖;否則,惡意攻擊可能會針對 req.cookie
值(很容易偽造)。請注意,簽署 cookie 並不會讓它「隱藏」或加密;但可以防止竄改(因為用於簽署的密碼是私密的)。
如果未傳送已簽署的 cookie,則屬性預設為 {}
。
// Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3
console.dir(req.signedCookies.user)
// => 'tobi'
如需更多資訊、問題或疑慮,請參閱 cookie-parser。
req.stale
表示要求是否「過時」,與 req.fresh
相反。如需更多資訊,請參閱 req.fresh。
console.dir(req.stale)
// => true
req.subdomains
要求網域名稱中的子網域陣列。
// Host: "tobi.ferrets.example.com"
console.dir(req.subdomains)
// => ['ferrets', 'tobi']
應用程式屬性 subdomain offset
預設為 2,用於判斷子網域區段的開頭。如要變更此行為,請使用 app.set 變更其值。
req.xhr
如果要求的 X-Requested-With
標頭欄位為「XMLHttpRequest」,表示要求是由 jQuery 等用戶端函式庫發出,則為 true
的布林值屬性。
console.dir(req.xhr)
// => true
方法
req.accepts(types)
根據要求的 Accept
HTTP 標頭欄位,檢查指定的內容類型是否可接受。此方法會傳回最佳比對,或如果沒有任何指定的內容類型可接受,則傳回 false
(在此情況下,應用程式應以 406 "Not Acceptable"
回應)。
type
值可以是單一 MIME 類型字串(例如「application/json」)、副檔名(例如「json」)、逗號分隔清單或陣列。對於清單或陣列,此方法會傳回最佳比對(如果有的話)。
// Accept: text/html
req.accepts('html')
// => "html"
// Accept: text/*, application/json
req.accepts('html')
// => "html"
req.accepts('text/html')
// => "text/html"
req.accepts(['json', 'text'])
// => "json"
req.accepts('application/json')
// => "application/json"
// Accept: text/*, application/json
req.accepts('image/png')
req.accepts('png')
// => false
// Accept: text/*;q=.5, application/json
req.accepts(['html', 'json'])
// => "json"
如需更多資訊,或如果您有任何問題或疑慮,請參閱 accepts。
req.acceptsCharsets(charset [, ...])
根據要求的 Accept-Charset
HTTP 標頭欄位,傳回指定的字元集的第一個可接受字元集。如果沒有任何指定的字元集可接受,則傳回 false
。
如需更多資訊,或如果您有任何問題或疑慮,請參閱 accepts。
req.acceptsEncodings(encoding [, ...])
根據要求的 Accept-Encoding
HTTP 標頭欄位,傳回指定的編碼的第一個可接受編碼。如果沒有任何指定的編碼可接受,則傳回 false
。
如需更多資訊,或如果您有任何問題或疑慮,請參閱 accepts。
req.acceptsLanguages([lang, ...])
根據要求的 Accept-Language
HTTP 標頭欄位,傳回指定語言的第一個已接受語言。如果沒有接受任何指定的語言,則傳回 false
。
如果沒有提供 lang
參數,則 req.acceptsLanguages()
會將 HTTP Accept-Language
標頭中的所有語言作為 Array
傳回。
如需更多資訊,或如果您有任何問題或疑慮,請參閱 accepts。
Express (4.x) 來源:request.js 第 179 行
Accepts (1.3) 來源:index.js 第 195 行
req.get(field)
傳回指定的 HTTP 要求標頭欄位(不分大小寫)。Referrer
和 Referer
欄位可以互換。
req.get('Content-Type')
// => "text/plain"
req.get('content-type')
// => "text/plain"
req.get('Something')
// => undefined
別名為 req.header(field)
。
req.is(type)
如果傳入要求的「Content-Type」HTTP 標頭欄位與 type
參數指定的 MIME 類型相符,則傳回相符的內容類型。如果要求沒有主體,則傳回 null
。否則傳回 false
。
// With Content-Type: text/html; charset=utf-8
req.is('html')
// => 'html'
req.is('text/html')
// => 'text/html'
req.is('text/*')
// => 'text/*'
// When Content-Type is application/json
req.is('json')
// => 'json'
req.is('application/json')
// => 'application/json'
req.is('application/*')
// => 'application/*'
req.is('html')
// => false
如需更多資訊,或如果您有任何問題或疑慮,請參閱 type-is。
req.param(name [, defaultValue])
已過時。請使用 req.params
、req.body
或 req.query
(視情況而定)。
當存在時,傳回參數 name
的值。
// ?name=tobi
req.param('name')
// => "tobi"
// POST name=tobi
req.param('name')
// => "tobi"
// /user/tobi for /user/:name
req.param('name')
// => "tobi"
按以下順序執行查詢
req.params
req.body
req.query
您也可以指定 defaultValue
,以在任何要求物件中找不到參數時設定預設值。
為了清楚起見,應優先直接存取 req.body
、req.params
和 req.query
,除非您真的接受每個物件的輸入。
必須載入主體剖析中介軟體,才能預測 req.param()
的運作方式。有關詳細資訊,請參閱 req.body。
req.range(size[, options])
Range
標頭剖析器。
size
參數為資源的最大大小。
options
參數為一個物件,可以有以下屬性。
屬性 | 類型 | 說明 |
---|---|---|
combine |
布林值 | 指定是否應合併重疊和相鄰的範圍,預設為 false 。當為 true 時,範圍會合併並回傳,就像是以這種方式在標頭中指定的一樣。 |
會回傳一個範圍陣列或表示剖析錯誤的負數。
-2
表示格式錯誤的標頭字串-1
表示無法滿足的範圍
// parse header from request
var range = req.range(1000)
// the type of the range
if (range.type === 'bytes') {
// the ranges
range.forEach(function (r) {
// do something with r.start and r.end
})
}
Response
res
物件表示 Express 應用程式在收到 HTTP 要求時傳送的 HTTP 回應。
在此文件和慣例中,物件總是稱為 res
(而 HTTP 要求為 req
),但其實際名稱是由您正在處理的回呼函式的參數決定的。
例如
app.get('/user/:id', function (req, res) {
res.send('user ' + req.params.id)
})
但您也可以使用
app.get('/user/:id', function (request, response) {
response.send('user ' + request.params.id)
})
res
物件是 Node 自身回應物件的加強版本,並支援所有 內建欄位和方法。
屬性
res.app
此屬性持有正在使用中介軟體的 Express 應用程式實例的參考。
res.app
與要求物件中的 req.app 屬性相同。
res.headersSent
布林值屬性,表示應用程式是否為回應傳送 HTTP 標頭。
app.get('/', function (req, res) {
console.dir(res.headersSent) // false
res.send('OK')
console.dir(res.headersSent) // true
})
res.locals
使用此屬性來設定可於使用 res.render 呈現的範本中存取的變數。設定在 res.locals
上的變數可用於單一要求-回應循環中,且不會在要求之間共用。
locals
物件由檢視引擎用於呈現回應。物件金鑰可能特別敏感,不應包含使用者控制的輸入,因為它可能會影響檢視引擎的運作或提供跨網站指令碼的途徑。請諮詢所用檢視引擎的說明文件以取得其他考量因素。
若要讓區域變數可在要求之間用於範本呈現,請改用 app.locals。
此屬性對於將要求層級資訊(例如要求路徑名稱、經過驗證的使用者、使用者設定等)公開到應用程式內呈現的範本中很有用。
app.use(function (req, res, next) {
// Make `user` and `authenticated` available in templates
res.locals.user = req.user
res.locals.authenticated = !req.user.anonymous
next()
})
方法
res.append(field [, value])
res.append()
受 Express v4.11.0+ 支援
將指定的 value
附加到 HTTP 回應標頭 field
。如果標頭尚未設定,則會使用指定的 value
建立標頭。value
參數可以是字串或陣列。
注意:在 res.append()
之後呼叫 res.set()
會重設先前設定的標頭值。
res.append('Link', ['<https://127.0.0.1/>', '<https://127.0.0.1:3000/>'])
res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly')
res.append('Warning', '199 Miscellaneous warning')
res.attachment([檔名])
將 HTTP 回應的 Content-Disposition
標頭欄位設為「attachment」。如果給定 檔名
,則會透過 res.type()
根據副檔名來設定內容類型,並設定 Content-Disposition
的「filename=」參數。
res.attachment()
// Content-Disposition: attachment
res.attachment('path/to/logo.png')
// Content-Disposition: attachment; filename="logo.png"
// Content-Type: image/png
res.cookie(名稱, 值 [, 選項])
將 Cookie 的 名稱
設為 值
。值
參數可以是字串或轉換為 JSON 的物件。
options
參數為一個物件,可以有以下屬性。
屬性 | 類型 | 說明 |
---|---|---|
domain |
字串 | Cookie 的網域名稱。預設為應用程式的網域名稱。 |
encode |
函數 | 用於 Cookie 值編碼的同步函式。預設為 encodeURIComponent 。 |
expires |
日期 | Cookie 在 GMT 中的到期日。如果未指定或設為 0,則會建立一個階段性 Cookie。 |
httpOnly |
布林值 | 將 Cookie 標記為只能由網路伺服器存取。 |
maxAge |
數字 | 方便的選項,用於設定相對於目前時間的到期時間(單位:毫秒)。 |
path |
字串 | Cookie 的路徑。預設為「/」。 |
partitioned |
布林值 | 指出 Cookie 應使用分區儲存空間來儲存。如需更多詳細資料,請參閱 具有獨立分區狀態的 Cookie (CHIPS)。 |
priority |
字串 | 「優先權」Set-Cookie 屬性的值。 |
secure |
布林值 | 標記 Cookie 僅供 HTTPS 使用。 |
signed |
布林值 | 指出 Cookie 是否應簽署。 |
sameSite |
布林值或字串 | 「SameSite」Set-Cookie 屬性的值。更多資訊請參閱 https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1。 |
res.cookie()
所做的所有事情就是使用提供的選項設定 HTTP Set-Cookie
標頭。任何未指定的選項都預設為 RFC 6265 中所述的值。
例如
res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true })
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true })
你可以透過多次呼叫 res.cookie
來在單一回應中設定多個 Cookie,例如
res
.status(201)
.cookie('access_token', 'Bearer ' + token, {
expires: new Date(Date.now() + 8 * 3600000) // cookie will be removed after 8 hours
})
.cookie('test', 'test')
.redirect(301, '/admin')
encode
選項允許你選擇用於 Cookie 值編碼的函式。不支援非同步函式。
範例使用案例:您需要為組織中的另一個網站設定全域性 cookie。這個其他網站(不在您的管理控制之下)不使用 URI 編碼的 cookie 值。
// Default encoding
res.cookie('some_cross_domain_cookie', 'http://mysubdomain.example.com', { domain: 'example.com' })
// Result: 'some_cross_domain_cookie=http%3A%2F%2Fmysubdomain.example.com; Domain=example.com; Path=/'
// Custom encoding
res.cookie('some_cross_domain_cookie', 'http://mysubdomain.example.com', { domain: 'example.com', encode: String })
// Result: 'some_cross_domain_cookie=http://mysubdomain.example.com; Domain=example.com; Path=/;'
maxAge
選項是一個便利選項,用於設定相對於當前時間(以毫秒為單位)的「過期時間」。以下內容等同於上述第二個範例。
res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
您可以傳遞一個物件作為 value
參數;然後它會序列化為 JSON,並由 bodyParser()
中介軟體進行剖析。
res.cookie('cart', { items: [1, 2, 3] })
res.cookie('cart', { items: [1, 2, 3] }, { maxAge: 900000 })
在使用 cookie-parser 中介軟體時,這個方法也支援已簽署的 cookie。只需包含已設定為 true
的 signed
選項。然後 res.cookie()
會使用傳遞給 cookieParser(secret)
的機密來簽署值。
res.cookie('name', 'tobi', { signed: true })
稍後您可以透過 req.signedCookie 物件來存取這個值。
res.clearCookie(name [, options])
清除由 name
指定的 cookie。有關 options
物件的詳細資訊,請參閱 res.cookie()。
只有當給定的 options
與傳遞給 res.cookie() 的 options
相同(不包括 expires
和 maxAge
)時,網路瀏覽器和其他相容的用戶端才會清除 cookie。
res.cookie('name', 'tobi', { path: '/admin' })
res.clearCookie('name', { path: '/admin' })
res.download(path [, filename] [, options] [, fn])
將 path
中的檔案傳輸為「附件」。通常,瀏覽器會提示使用者下載。預設情況下,Content-Disposition
標頭的「filename=」參數會從 path
引數中衍生,但可以使用 filename
參數覆寫。如果 path
是相對路徑,則它會根據處理程序的目前工作目錄或(如果已提供)root
選項為基礎。
這個 API 提供存取執行中檔案系統上的資料。請確保(a)如果 path
引數包含使用者輸入,則建構其方式是安全的,或(b)將 root
選項設定為目錄的絕對路徑,以包含其中的存取權。
當提供 root
選項時,Express 會驗證作為 path
提供的相對路徑會在指定的 root
選項中解析。
下表提供 options
參數的詳細資料。
自 Express v4.16.0 起支援選用 options
參數。
屬性 | 說明 | 預設 | 可用性 |
---|---|---|---|
maxAge |
以毫秒或 ms 格式 的字串設定 Cache-Control 標頭的 max-age 屬性 |
0 | 4.16+ |
root |
相對檔案名稱的根目錄。 | 4.18+ | |
lastModified |
將 Last-Modified 標頭設定為檔案在作業系統上的最後修改日期。設定為 false 以停用它。 |
已啟用 | 4.16+ |
headers |
包含要與檔案一起提供的 HTTP 標頭的物件。標頭 Content-Disposition 會被 filename 參數覆寫。 |
4.16+ | |
dotfiles |
提供 dotfile 的選項。可能的值為「allow」、「deny」、「ignore」。 | 「忽略」 | 4.16+ |
acceptRanges |
啟用或停用接受範圍請求。 | true |
4.16+ |
cacheControl |
啟用或停用設定 Cache-Control 回應標頭。 |
true |
4.16+ |
immutable |
在 Cache-Control 回應標頭中啟用或停用 immutable 指示。如果啟用,也應該指定 maxAge 選項以啟用快取。immutable 指示會防止支援的用戶端在 maxAge 選項的存續期間提出條件式請求,以檢查檔案是否已變更。 |
false |
4.16+ |
當傳輸完成或發生錯誤時,此方法會呼叫回呼函式 fn(err)
。如果指定回呼函式且發生錯誤,回呼函式必須明確處理回應程序,方法是結束請求-回應循環或將控制權傳遞給下一個路由。
res.download('/report-12345.pdf')
res.download('/report-12345.pdf', 'report.pdf')
res.download('/report-12345.pdf', 'report.pdf', function (err) {
if (err) {
// Handle error, but keep in mind the response may be partially-sent
// so check res.headersSent
} else {
// decrement a download credit, etc.
}
})
res.end([data] [, encoding])
結束回應程序。此方法實際上來自 Node 核心,特別是 http.ServerResponse 的 response.end() 方法。
用於在沒有任何資料的情況下快速結束回應。如果您需要回應資料,請改用 res.send() 和 res.json() 等方法。
res.end()
res.status(404).end()
res.format(object)
當存在時,對請求物件上的 Accept
HTTP 標頭執行內容協商。它使用 req.accepts() 根據可接受類型按其品質值排序,為請求選擇處理常式。如果未指定標頭,則會呼叫第一個回呼。如果找不到匹配項,伺服器會回應 406「不可接受」,或呼叫 default
回呼。
當選擇回呼時,會設定 Content-Type
回應標頭。不過,你可以使用 res.set()
或 res.type()
等方法在回呼中變更它。
當 Accept
標頭欄位設定為「application/json」或「*/json」時,以下範例會回應 { "message": "hey" }
(但如果是「*/*」,回應會是「hey」)。
res.format({
'text/plain': function () {
res.send('hey')
},
'text/html': function () {
res.send('<p>hey</p>')
},
'application/json': function () {
res.send({ message: 'hey' })
},
default: function () {
// log the request and respond with 406
res.status(406).send('Not Acceptable')
}
})
除了正規化的 MIME 類型外,你也可以使用對應到這些類型的副檔名,讓實作更簡潔
res.format({
text: function () {
res.send('hey')
},
html: function () {
res.send('<p>hey</p>')
},
json: function () {
res.send({ message: 'hey' })
}
})
res.get(field)
傳回 field
指定的 HTTP 回應標頭。比對時不區分大小寫。
res.get('Content-Type')
// => "text/plain"
res.json([body])
傳送 JSON 回應。此方法會傳送一個回應(內容類型正確),這個回應是使用 JSON.stringify() 將參數轉換為 JSON 字串。
參數可以是任何 JSON 類型,包括物件、陣列、字串、布林值、數字或 null,你也可以用它將其他值轉換為 JSON。
res.json(null)
res.json({ user: 'tobi' })
res.status(500).json({ error: 'message' })
res.jsonp([body])
傳送支援 JSONP 的 JSON 回應。此方法與 res.json()
相同,但它會選擇加入 JSONP 回呼支援。
res.jsonp(null)
// => callback(null)
res.jsonp({ user: 'tobi' })
// => callback({ "user": "tobi" })
res.status(500).jsonp({ error: 'message' })
// => callback({ "error": "message" })
預設的 JSONP 回呼名稱就是 callback
。使用 jsonp 回呼名稱 設定來覆寫它。
以下是一些使用相同程式碼的 JSONP 回應範例
// ?callback=foo
res.jsonp({ user: 'tobi' })
// => foo({ "user": "tobi" })
app.set('jsonp callback name', 'cb')
// ?cb=foo
res.status(500).jsonp({ error: 'message' })
// => foo({ "error": "message" })
res.links(links)
將提供為參數屬性的 links
加入回應的 Link
HTTP 標頭欄位中。
例如,以下呼叫
res.links({
next: 'http://api.example.com/users?page=2',
last: 'http://api.example.com/users?page=5'
})
會產生以下結果
Link: <http://api.example.com/users?page=2>; rel="next",
<http://api.example.com/users?page=5>; rel="last"
res.location(path)
將回應 Location
HTTP 標頭設定為指定的 path
參數。
res.location('/foo/bar')
res.location('http://example.com')
res.location('back')
「back」的 path
值有特殊意義,它指的是請求的 Referer
標頭中指定的 URL。如果未指定 Referer
標頭,它指的是「/」。
在對 URL 編碼(如果尚未編碼)後,Express 會在 Location
標頭中將指定的 URL 傳遞給瀏覽器,而不會進行任何驗證。
瀏覽器負責從目前的 URL 或參考 URL,以及在 Location
標頭中指定的 URL 中,推導出預期的 URL;並據此重新導向使用者。
res.redirect([status,] path)
重新導向到從指定的 path
推導出的 URL,並具有指定的 status
,一個對應到 HTTP 狀態碼 的正整數。如果未指定,status
預設為「302 已找到」。
res.redirect('/foo/bar')
res.redirect('http://example.com')
res.redirect(301, 'http://example.com')
res.redirect('../login')
重新導向可以是完全限定的 URL,用於重新導向到不同的網站
res.redirect('http://google.com')
重新導向可以相對於主機名稱的根目錄。例如,如果應用程式在 http://example.com/admin/post/new
,下列會重新導向到 URL http://example.com/admin
res.redirect('/admin')
重新導向可以相對於目前的 URL。例如,從 http://example.com/blog/admin/
(注意尾端的斜線),下列會重新導向到 URL http://example.com/blog/admin/post/new
。
res.redirect('post/new')
從 http://example.com/blog/admin
(沒有尾端的斜線)重新導向到 post/new
,會重新導向到 http://example.com/blog/post/new
。
如果你發現上述行為令人困惑,可以將路徑區段想成目錄(有尾端的斜線)和檔案,這樣就會開始有道理了。
路徑相對的重新導向也是可能的。如果你在 http://example.com/admin/post/new
,下列會重新導向到 http://example.com/admin/post
res.redirect('..')
back
重新導向會將要求重新導向回 參考者,當參考者不存在時預設為 /
。
res.redirect('back')
res.render(view [, locals] [, callback])
呈現 view
並將呈現的 HTML 字串傳送給客戶端。選用參數
locals
,一個物件,其屬性定義檢視的局部變數。callback
,一個回呼函式。如果提供,此方法會同時傳回可能的錯誤和呈現的字串,但不會執行自動化的回應。當發生錯誤時,此方法會在內部呼叫next(err)
。
view
參數是一個字串,它是要呈現的檢視檔案的檔案路徑。這可以是絕對路徑,或是相對於 views
設定的路徑。如果路徑不包含檔案副檔名,則 view engine
設定會決定檔案副檔名。如果路徑包含檔案副檔名,則 Express 會載入指定範本引擎的模組(透過 require()
),並使用載入模組的 __express
函式來呈現它。
如需更多資訊,請參閱 使用 Express 的範本引擎。
view
參數執行檔案系統操作,例如從磁碟讀取檔案和評估 Node.js 模組,因此出於安全原因,不應包含來自最終使用者的輸入。
locals
物件由檢視引擎用於呈現回應。物件金鑰可能特別敏感,不應包含使用者控制的輸入,因為它可能會影響檢視引擎的運作或提供跨網站指令碼的途徑。請諮詢所用檢視引擎的說明文件以取得其他考量因素。
區域變數 cache
啟用檢視快取。將它設為 true
,以在開發期間快取檢視;在預設情況下,檢視快取會在製作環境中啟用。
// send the rendered view to the client
res.render('index')
// if a callback is specified, the rendered HTML string has to be sent explicitly
res.render('index', function (err, html) {
res.send(html)
})
// pass a local variable to the view
res.render('user', { name: 'Tobi' }, function (err, html) {
// ...
})
res.req
此屬性持有與此回應物件相關的 請求物件 的參考。res.send([body])
傳送 HTTP 回應。
body
參數可以是 Buffer
物件、String
、物件、Boolean
或 Array
。例如
res.send(Buffer.from('whoop'))
res.send({ some: 'json' })
res.send('<p>some html</p>')
res.status(404).send('Sorry, we cannot find that!')
res.status(500).send({ error: 'something blew up' })
此方法會執行許多對簡單非串流回應有用的工作:例如,它會自動指定 Content-Length
HTTP 回應標頭欄位(除非先前已定義),並提供自動 HEAD 和 HTTP 快取新鮮度支援。
當參數是 Buffer
物件時,此方法會將 Content-Type
回應標頭欄位設為「application/octet-stream」,除非先前已定義,如下所示
res.set('Content-Type', 'text/html')
res.send(Buffer.from('<p>some html</p>'))
當參數是 String
時,此方法會將 Content-Type
設為「text/html」
res.send('<p>some html</p>')
當參數是 Array
或 Object
時,Express 會以 JSON 表示回應
res.send({ user: 'tobi' })
res.send([1, 2, 3])
res.sendFile(path [, options] [, fn])
res.sendFile()
受 Express v4.8.0 以上版本支援。
傳輸指定 path
的檔案。根據檔名的副檔名設定 Content-Type
回應 HTTP 標頭欄位。除非在 options 物件中設定 root
選項,否則 path
必須是檔案的絕對路徑。
此 API 提供存取正在執行的檔案系統的資料。請確保(a)建構 path
參數為絕對路徑的方式是安全的,如果它包含使用者輸入,或(b)將 root
選項設為目錄的絕對路徑,以包含在其中存取。
當提供 root
選項時,允許 path
參數為相對路徑,包括包含 ..
。Express 會驗證提供為 path
的相對路徑會在給定的 root
選項中解析。
下表提供 options
參數的詳細資料。
屬性 | 說明 | 預設 | 可用性 |
---|---|---|---|
maxAge |
以毫秒或 ms 格式 的字串設定 Cache-Control 標頭的 max-age 屬性 |
0 | |
root |
相對檔案名稱的根目錄。 | ||
lastModified |
將 Last-Modified 標頭設定為檔案在作業系統上的最後修改日期。設定為 false 以停用它。 |
已啟用 | 4.9.0+ |
headers |
包含要與檔案一起提供的 HTTP 標頭的物件。 | ||
dotfiles |
提供 dotfile 的選項。可能的值為「allow」、「deny」、「ignore」。 | 「忽略」 | |
acceptRanges |
啟用或停用接受範圍請求。 | true |
4.14+ |
cacheControl |
啟用或停用設定 Cache-Control 回應標頭。 |
true |
4.14+ |
immutable |
在 Cache-Control 回應標頭中啟用或停用 immutable 指示。如果啟用,也應該指定 maxAge 選項以啟用快取。immutable 指示會防止支援的用戶端在 maxAge 選項的存續期間提出條件式請求,以檢查檔案是否已變更。 |
false |
4.16+ |
當傳輸完成或發生錯誤時,此方法會呼叫回呼函式 fn(err)
。如果指定回呼函式且發生錯誤,回呼函式必須明確處理回應程序,方法是結束請求-回應循環或將控制權傳遞給下一個路由。
以下是一個使用 res.sendFile
及其所有參數的範例。
app.get('/file/:name', function (req, res, next) {
var options = {
root: path.join(__dirname, 'public'),
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
}
var fileName = req.params.name
res.sendFile(fileName, options, function (err) {
if (err) {
next(err)
} else {
console.log('Sent:', fileName)
}
})
})
以下範例說明如何使用 res.sendFile
提供細緻的檔案提供支援
app.get('/user/:uid/photos/:file', function (req, res) {
var uid = req.params.uid
var file = req.params.file
req.user.mayViewFilesFrom(uid, function (yes) {
if (yes) {
res.sendFile('/uploads/' + uid + '/' + file)
} else {
res.status(403).send("Sorry! You can't see that.")
}
})
})
如需更多資訊,或如果您有任何問題或疑慮,請參閱 send。
res.sendStatus(statusCode)
將回應 HTTP 狀態碼設定為 statusCode
,並將註冊的狀態訊息作為文字回應主體傳送。如果指定了未知的狀態碼,回應主體將僅為代碼號碼。
res.sendStatus(404)
某些版本的 Node.js 會在 res.statusCode
設定為無效的 HTTP 狀態碼(超出 100
至 599
範圍)時引發例外狀況。請參閱所使用 Node.js 版本的 HTTP 伺服器文件。
res.set(field [, value])
將回應的 HTTP 標頭 field
設定為 value
。若要一次設定多個欄位,請傳遞一個物件作為參數。
res.set('Content-Type', 'text/plain')
res.set({
'Content-Type': 'text/plain',
'Content-Length': '123',
ETag: '12345'
})
別名為 res.header(field [, value])
。
res.status(code)
設定回應的 HTTP 狀態。它是 Node 的 response.statusCode 的可串接別名。
res.status(403).end()
res.status(400).send('Bad Request')
res.status(404).sendFile('/absolute/path/to/404.png')
res.type(type)
將 Content-Type
HTTP 標頭設定為由指定的 type
所決定的 MIME 類型。如果 type
包含 “/” 字元,則將 Content-Type
設定為 type
的確切值,否則假設它是一個檔案副檔名,且 MIME 類型會使用 express.static.mime.lookup()
方法在對應中查詢。
res.type('.html')
// => 'text/html'
res.type('html')
// => 'text/html'
res.type('json')
// => 'application/json'
res.type('application/json')
// => 'application/json'
res.type('png')
// => 'image/png'
res.vary(field)
如果 Vary
回應標頭中尚未存在該欄位,則將其新增至其中。
res.vary('User-Agent').render('docs')
Router
router
物件是中介軟體和路由的獨立執行個體。您可以將它視為一個“迷你應用程式”,只能執行中介軟體和路由功能。每個 Express 應用程式都有一個內建的應用程式路由器。
路由器本身就像中介軟體一樣,因此您可以將它用作 app.use() 的引數,或作為另一個路由器的 use() 方法的引數。
頂層 express
物件有一個 Router() 方法,用於建立新的 router
物件。
建立路由器物件後,您可以像應用程式一樣,新增中介軟體和 HTTP 方法路由(例如 get
、put
、post
等)到其中。例如
// invoked for any requests passed to this router
router.use(function (req, res, next) {
// .. some logic here .. like any other middleware
next()
})
// will handle any request that ends in /events
// depends on where the router is "use()'d"
router.get('/events', function (req, res, next) {
// ..
})
接著,您可以使用路由器處理特定根 URL,將您的路由區分到不同的檔案,甚至迷你應用程式中。
// only requests to /calendar/* will be sent to our "router"
app.use('/calendar', router)
方法
router.all(path, [callback, ...] callback)
此方法就像 router.METHOD()
方法,只不過它比對所有 HTTP 方法(動詞)。
此方法對於特定路徑前綴或任意比對的「全域」邏輯對應非常有用。例如,如果您將下列路由置於所有其他路由定義的最上方,它會要求從該點開始的所有路由都需要驗證,並自動載入使用者。請記住,這些回呼不必作為終點作用;loadUser
可以執行一項任務,然後呼叫 next()
以繼續比對後續路由。
router.all('*', requireAuthentication, loadUser)
或等效的
router.all('*', requireAuthentication)
router.all('*', loadUser)
另一個範例是白名單「全域」功能。此範例與之前非常類似,但它只限制以「/api」為前綴的路徑
router.all('/api/*', requireAuthentication)
router.METHOD(path, [callback, ...] callback)
router.METHOD()
方法在 Express 中提供路由功能,其中 METHOD 是 HTTP 方法之一,例如 GET、PUT、POST 等,以小寫表示。因此,實際的方法為 router.get()
、router.post()
、router.put()
等。
如果在 router.get()
之前未針對路徑呼叫 router.head()
,則除了 GET
方法之外,router.get()
函式也會自動針對 HTTP HEAD
方法呼叫。
您可以提供多個回呼,所有回呼都受到同等對待,且行為就像中間軟體一樣,只不過這些回呼可以呼叫 next('route')
以略過剩餘的路由回呼。您可以使用此機制對路由執行前置條件,然後在沒有理由繼續執行已比對的路由時,將控制權傳遞給後續路由。
以下範例說明最簡單的路由定義。Express 會將路徑字串轉換為正規表示式,並在內部用來比對收到的要求。在執行這些比對時,不會考慮查詢字串,例如「GET /」會比對到以下路由,而「GET /?name=tobi」也會比對到。
router.get('/', function (req, res) {
res.send('hello world')
})
你也可以使用正規表示式,如果你有非常特定的限制,這會很有用,例如以下範例會比對到「GET /commits/71dbb9c」以及「GET /commits/71dbb9c..4c084f9」。
router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function (req, res) {
var from = req.params[0]
var to = req.params[1] || 'HEAD'
res.send('commit range ' + from + '..' + to)
})
router.param(name, callback)
將 callback 觸發器新增到路由參數,其中 name
是參數的名稱,而 callback
是 callback 函式。雖然 name
在技術上是可選的,但從 Express v4.11.0 開始,不使用此方法會被視為不建議使用(請見下方說明)。
callback 函式的參數為
req
,要求物件。res
,回應物件。next
,表示下一個中間件函式。name
參數的值。- 參數的名稱。
與 app.param()
不同,router.param()
不接受路由參數陣列。
例如,當路由路徑中出現 :user
時,你可以對應使用者載入邏輯,以自動將 req.user
提供給路由,或對參數輸入執行驗證。
router.param('user', function (req, res, next, id) {
// try to get the user details from the User model and attach it to the request object
User.find(id, function (err, user) {
if (err) {
next(err)
} else if (user) {
req.user = user
next()
} else {
next(new Error('failed to load user'))
}
})
})
參數 callback 函式是定義它們的路由器的區域性函式。它們不會被掛載的應用程式或路由器繼承。因此,在 router
中定義的參數 callback 只會由在 router
路由中定義的路由參數觸發。
參數 callback 在要求回應週期中只會被呼叫一次,即使參數在多個路由中比對到,如下列範例所示。
router.param('id', function (req, res, next, id) {
console.log('CALLED ONLY ONCE')
next()
})
router.get('/user/:id', function (req, res, next) {
console.log('although this matches')
next()
})
router.get('/user/:id', function (req, res) {
console.log('and this matches too')
res.end()
})
在 GET /user/42
中,會列印下列內容
CALLED ONLY ONCE
although this matches
and this matches too
以下部分說明 router.param(callback)
,它已在 v4.11.0 中被視為不建議使用。
router.param(name, callback)
方法的行為可以透過只傳遞一個函式給 router.param()
而完全改變。這個函式是 router.param(name, callback)
應如何運作的客製化實作 - 它接受兩個參數,而且必須傳回一個中間件。
此函數的第一個參數是要擷取的 URL 參數名稱,第二個參數可以是任何 JavaScript 物件,可用於傳回中間件實作。
函數傳回的中間件決定擷取 URL 參數時會發生什麼事。
在此範例中,router.param(name, callback)
簽章被修改為 router.param(name, accessId)
。router.param()
現在會接受一個名稱和一個數字,而不是接受一個名稱和一個 callback。
var express = require('express')
var app = express()
var router = express.Router()
// customizing the behavior of router.param()
router.param(function (param, option) {
return function (req, res, next, val) {
if (val === option) {
next()
} else {
res.sendStatus(403)
}
}
})
// using the customized router.param()
router.param('id', '1337')
// route to trigger the capture
router.get('/user/:id', function (req, res) {
res.send('OK')
})
app.use(router)
app.listen(3000, function () {
console.log('Ready')
})
在此範例中,router.param(name, callback)
簽章保持不變,但已定義自訂資料類型檢查函式來驗證使用者 ID 的資料類型,而非中介軟體回呼。
router.param(function (param, validator) {
return function (req, res, next, val) {
if (validator(val)) {
next()
} else {
res.sendStatus(403)
}
}
})
router.param('id', function (candidate) {
return !isNaN(parseFloat(candidate)) && isFinite(candidate)
})
router.route(path)
傳回單一路由的執行個體,您可使用它來處理 HTTP 動詞(可搭配中介軟體)。使用 router.route()
可避免重複路由命名,進而避免輸入錯誤。
根據上述 router.param()
範例,以下程式碼顯示如何使用 router.route()
來指定各種 HTTP 方法處理常式。
var router = express.Router()
router.param('user_id', function (req, res, next, id) {
// sample user, would actually fetch from DB, etc...
req.user = {
id: id,
name: 'TJ'
}
next()
})
router.route('/users/:user_id')
.all(function (req, res, next) {
// runs for all HTTP verbs first
// think of it as route specific middleware!
next()
})
.get(function (req, res, next) {
res.json(req.user)
})
.put(function (req, res, next) {
// just an example of maybe updating the user
req.user.name = req.params.name
// save user ... etc
res.json(req.user)
})
.post(function (req, res, next) {
next(new Error('not implemented'))
})
.delete(function (req, res, next) {
next(new Error('not implemented'))
})
此方法重新使用單一 /users/:user_id
路徑,並為各種 HTTP 方法新增處理常式。
注意:當您使用 router.route()
時,中介軟體排序會根據建立 路由 的時間為依據,而非將方法處理常式新增至路由的時間。基於此目的,您可以將方法處理常式視為屬於新增至其的路由。
router.use([path], [function, ...] function)
使用指定的中介軟體函式或函式,搭配選用掛載路徑 path
,預設為「/」。
此方法類似於 app.use()。下方說明一個簡單的範例和使用案例。請參閱 app.use() 以取得更多資訊。
中介軟體就像水管:要求從定義的第一個中介軟體函式開始,並依序「向下」處理中介軟體堆疊,以處理它們符合的每個路徑。
var express = require('express')
var app = express()
var router = express.Router()
// simple logger for this router's requests
// all requests to this router will first hit this middleware
router.use(function (req, res, next) {
console.log('%s %s %s', req.method, req.url, req.path)
next()
})
// this will only be invoked if the path starts with /bar from the mount point
router.use('/bar', function (req, res, next) {
// ... maybe some additional /bar logging ...
next()
})
// always invoked
router.use(function (req, res, next) {
res.send('Hello World')
})
app.use('/foo', router)
app.listen(3000)
「掛載」路徑會被移除,而且中介軟體函式不會看到它。此功能的主要影響是,掛載的中介軟體函式可以在不變更程式碼的情況下運作,不論其「前置」路徑名稱為何。
您使用 router.use()
定義中介軟體的順序非常重要。它們會依序呼叫,因此順序會定義中介軟體優先順序。例如,記錄器通常會是您使用的第一個中介軟體,以便記錄每個要求。
var logger = require('morgan')
var path = require('path')
router.use(logger())
router.use(express.static(path.join(__dirname, 'public')))
router.use(function (req, res) {
res.send('Hello')
})
現在假設您想忽略靜態檔案的記錄請求,但繼續記錄在 logger()
之後定義的路由和中間件。您只需將對 express.static()
的呼叫移到最上面,然後再加入記錄器中間件
router.use(express.static(path.join(__dirname, 'public')))
router.use(logger())
router.use(function (req, res) {
res.send('Hello')
})
另一個範例是從多個目錄提供檔案,讓「./public」優先於其他目錄
router.use(express.static(path.join(__dirname, 'public')))
router.use(express.static(path.join(__dirname, 'files')))
router.use(express.static(path.join(__dirname, 'uploads')))
router.use()
方法也支援命名參數,以便您用於其他路由器的掛載點可以受益於使用命名參數進行預載入。
注意:雖然這些中間件函式是透過特定路由器加入的,但何時執行它們是由它們所附加的路徑定義的(而不是路由器)。因此,透過一個路由器加入的中間件可能會在其他路由器的路由相符時執行。例如,此程式碼顯示兩個不同的路由器掛載在同一路徑上
var authRouter = express.Router()
var openRouter = express.Router()
authRouter.use(require('./authenticate').basic(usersdb))
authRouter.get('/:user_id/edit', function (req, res, next) {
// ... Edit user UI ...
})
openRouter.get('/', function (req, res, next) {
// ... List users ...
})
openRouter.get('/:user_id', function (req, res, next) {
// ... View user ...
})
app.use('/users', authRouter)
app.use('/users', openRouter)
即使驗證中間件是透過 authRouter
加入的,它也會執行在 openRouter
定義的路由上,因為兩個路由器都掛載在 /users
上。若要避免這種行為,請為每個路由器使用不同的路徑。