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 且只會查看內容類型標頭與 type 選項相符的請求的中介軟體。此剖析器接受主體的任何 Unicode 編碼,並支援自動膨脹 gzip 和 deflate 編碼。
在中介軟體之後(例如 req.body),會在 request 物件上填充一個包含剖析資料的新 body 物件,或者如果沒有要剖析的主體、內容類型不符或發生錯誤,則會填充一個空物件({})。
由於 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 |
此選項(如果提供)會呼叫為 verify(req, res, buf, encoding) ,其中 buf 是原始請求主體的 Buffer ,而 encoding 是請求的編碼。可以透過擲回錯誤來中止解析。 |
函式 | undefined |
express.raw([options])
此中間件在 Express v4.17.0 以後版本中可用。
這是 Express 中的內建中間件函式。它會將輸入請求酬載解析成 Buffer
,並基於 body-parser。
傳回將所有主體剖析為 Buffer
的中間件,且只查看 Content-Type
標頭與 type
選項相符的請求。此剖析器接受主體的任何 Unicode 編碼,並支援自動膨脹 gzip
和 deflate
編碼。
在中間件 (即 req.body
) 後,一個包含剖析資料的新 body
Buffer
會填充到 request
物件中,或是一個空物件 ({}
),如果沒有主體可剖析、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 |
此選項(如果提供)會呼叫為 verify(req, res, buf, encoding) ,其中 buf 是原始請求主體的 Buffer ,而 encoding 是請求的編碼。可以透過擲回錯誤來中止解析。 |
函式 | undefined |
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
,就像應用程式一樣。
如需更多資訊,請參閱 Router。
express.static(root, [options])
這是 Express 中內建的中間件函式。它提供靜態檔案,並基於 serve-static。
注意:為了獲得最佳結果,使用反向代理快取,以提升提供靜態資源的效能。
root
參數指定提供靜態資源的根目錄。此函式會將 req.url
與提供的 root
目錄結合,以決定要提供的檔案。如果找不到檔案,它會呼叫 next()
,而不是傳送 404 回應,以繼續執行下一個中間件,允許堆疊和回退。
下表說明 options
物件的屬性。另請參閱 以下範例。
屬性 | 說明 | 類型 | 預設值 |
---|---|---|---|
dotfiles |
決定如何處理點檔(以點號「.」開頭的檔案或目錄)。 請參閱以下 dotfiles。 |
字串 | 「ignore」 |
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([options])
此中間件在 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 |
此選項(如果提供)會呼叫為 verify(req, res, buf, encoding) ,其中 buf 是原始請求主體的 Buffer ,而 encoding 是請求的編碼。可以透過擲回錯誤來中止解析。 |
函式 | undefined |
express.urlencoded([options])
此中間件在 Express v4.16.0 以上版本中可用。
這是 Express 中的內建中間件函式。它會解析帶有 URL 編碼有效負載的傳入請求,並基於 body-parser。
傳回僅解析 URL 編碼主體的中間件,並且僅查看 Content-Type
標頭與 type
選項相符的請求。此解析器僅接受主體的 UTF-8 編碼,並支援自動膨脹 gzip
和 deflate
編碼。
在中間件 (即 req.body
) 之後,會在 request
物件上填充包含已解析資料的新 body
物件,或者如果沒有要解析的主體、Content-Type
不相符或發生錯誤,則會填充一個空物件 ({}
)。此物件將包含鍵值對,其中值可以是字串或陣列 (當 extended
為 false
時),或任何類型 (當 extended
為 true
時)。
由於 req.body 的形狀是根據使用者控制的輸入,因此此物件中的所有屬性和值都不受信任,在信任之前應該驗證。例如,req.body.foo.toString() 可能會以多種方式失敗,例如 foo 可能不存在或不是字串,而 toString 可能不是函式,而是字串或其他使用者輸入。
下表說明選用 options 物件的屬性。
屬性 | 說明 | 類型 | 預設值 |
---|---|---|---|
extended |
此選項允許在使用 querystring 函式庫 (當 false 時) 或 qs 函式庫 (當 true 時) 解析 URL 編碼資料之間進行選擇。「延伸」語法允許將豐富的物件和陣列編碼成 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 |
此選項(如果提供)會呼叫為 verify(req, res, buf, encoding) ,其中 buf 是原始請求主體的 Buffer ,而 encoding 是請求的編碼。可以透過擲回錯誤來中止解析。 |
函式 | undefined |
應用程式
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
app 設定值的值,其中 name
是 app 設定值表格 中的其中一個字串。例如
app.get('title')
// => undefined
app.set('title', 'My Site')
app.get('title')
// => "My Site"
app.get(路徑, 回呼 [, 回呼 ...])
將 HTTP GET 要求路由到指定路徑,並使用指定的回呼函數。
引數
引數 | 說明 | 預設值 |
---|---|---|
path |
呼叫中間件函式的路徑;可以是下列任何一種
|
「/」(根路徑) |
回呼 |
回呼函式;可以是
您可以提供多個回呼函式,它們的行為就像中介軟體,但這些回呼可以呼叫 由於 路由器 和 應用程式 實作中介軟體介面,因此您可以像使用其他任何中介軟體函式一樣使用它們。 如需範例,請參閱 中介軟體回呼函式範例。 |
無 |
如需更多資訊,請參閱 路由指南。
範例
app.get('/', function (req, res) {
res.send('GET request to homepage')
})
app.listen(路徑, [回呼])
啟動 UNIX Socket,並在指定路徑上監聽連線。此方法與 Node 的 http.Server.listen() 相同。
var express = require('express')
var app = express()
app.listen('/tmp/sock')
app.listen([埠[, 主機[, 積壓]]][, 回呼])
在指定的主機和埠上繫結並監聽連線。此方法與 Node 的 http.Server.listen() 相同。
如果省略埠或埠為 0,作業系統會指派一個任意未使用的埠,這對於自動化任務(例如測試等)很有用。
var express = require('express')
var app = express()
app.listen(3000)
express()
回傳的 app
實際上是 JavaScript 函數
,設計為傳遞給 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(路徑, 回呼 [, 回呼 ...])
路由 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()
,則會自動針對 HTTP GET
方法和 HEAD
方法呼叫 app.get()
函式。
方法 app.all()
不是衍生自任何 HTTP 方法,而且會針對 所有 HTTP 要求方法載入指定路徑的中介軟體。如需進一步資訊,請參閱 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'))
}
})
})
Param 回呼函式會限定在定義它們的路由器中。已掛載的應用程式或路由器不會繼承它們。因此,在 app
中定義的 param 回呼函式只會由 app
路由中定義的路由參數觸發。
所有 param 回呼函式都會在 param 出現的任何路由的任何處理常式之前呼叫,而且它們在一個要求回應週期中只會呼叫一次,即使參數在多個路由中相符,如以下範例所示。
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)
})
「.
」字元無法用於擷取擷取 regexp 中的字元。例如,您無法使用 '/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(路徑, 回呼 [, 回呼 ...])
將 HTTP POST 要求路由到指定的路徑,並使用指定的回呼函式。如需更多資訊,請參閱 路由指南。
引數
引數 | 說明 | 預設值 |
---|---|---|
path |
呼叫中間件函式的路徑;可以是下列任何一種
|
「/」(根路徑) |
回呼 |
回呼函式;可以是
您可以提供多個回呼函式,它們的行為就像中介軟體,但這些回呼可以呼叫 由於 路由器 和 應用程式 實作中介軟體介面,因此您可以像使用其他任何中介軟體函式一樣使用它們。 如需範例,請參閱 中介軟體回呼函式範例。 |
無 |
範例
app.post('/', function (req, res) {
res.send('POST request to homepage')
})
app.put(路徑, 回呼 [, 回呼 ...])
將 HTTP PUT 要求路由到指定的路徑,並使用指定的回呼函式。
引數
引數 | 說明 | 預設值 |
---|---|---|
path |
呼叫中間件函式的路徑;可以是下列任何一種
|
「/」(根路徑) |
回呼 |
回呼函式;可以是
您可以提供多個回呼函式,它們的行為就像中介軟體,但這些回呼可以呼叫 由於 路由器 和 應用程式 實作中介軟體介面,因此您可以像使用其他任何中介軟體函式一樣使用它們。 如需範例,請參閱 中介軟體回呼函式範例。 |
無 |
範例
app.put('/', function (req, res) {
res.send('PUT request to homepage')
})
app.render(檢視, [區域變數], 回呼)
透過 回呼
函式傳回檢視的已呈現 HTML。它接受一個選用參數,該參數是一個包含檢視區域變數的物件。它就像 res.render(),只不過它無法自行將已呈現的檢視傳送給用戶端。
將 app.render()
視為一個用於產生已呈現檢視字串的工具函式。在內部,res.render()
使用 app.render()
來呈現檢視。
檢視
參數會執行檔案系統作業,例如從磁碟讀取檔案和評估 Node.js 模組,因此出於安全考量,不應包含來自最終使用者的輸入。
locals
物件由檢視引擎用於呈現回應。物件金鑰可能特別敏感,不應包含使用者控制的輸入,因為它可能會影響檢視引擎的運作或提供跨網站指令碼路徑。請參閱所用檢視引擎的文件,以了解其他考量因素。
區域變數 快取
保留用於啟用檢視快取。如果您要在開發期間快取檢視,請將其設定為 true
;在製作環境中,檢視快取會預設啟用。
app.render('email', function (err, html) {
// ...
})
app.render('email', { name: 'Tobi' }, function (err, html) {
// ...
})
app.route(路徑)
傳回單一路由的執行個體,然後您可以使用它來處理 HTTP 動詞,並搭配選用的中介軟體。使用 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(名稱, 值)
將設定 名稱
指定給 值
。您可以儲存任何想要的數值,但某些名稱可拿來設定伺服器的行為。這些特殊名稱會列在 應用程式設定表格 中。
針對布林屬性呼叫 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」會被視為相同。 注意:子應用程式會繼承此設定的值。 |
不適用(未定義) |
|
字串 | 環境模式。請務必在生產環境中設定為「生產」;請參閱 生產最佳實務:效能和可靠性。 |
|
|
變數 |
設定 ETag 回應標頭。有關可能的值,請參閱 |
|
|
字串 | 指定預設的 JSONP 回呼名稱。 |
「callback」 |
|
布林值 |
啟用從 注意:子應用程式會繼承此設定的值。 |
不適用(未定義) |
|
變數 | JSON.stringify 使用的 「替換」引數。
注意:子應用程式會繼承此設定的值。 |
不適用(未定義) |
|
變數 | JSON.stringify 使用的 「空格」引數。這通常設定為用於縮排美化 JSON 的空格數。
注意:子應用程式會繼承此設定的值。 |
不適用(未定義) |
|
變數 |
透過將值設定為 簡單查詢剖析器是基於 Node 的原生查詢剖析器 querystring。 進階查詢剖析器是基於 qs。 自訂查詢字串剖析函式將會收到完整的查詢字串,且必須傳回查詢金鑰及其值的物件。 |
"進階" |
|
布林值 | 啟用嚴格路由。啟用時,路由器會將「/foo」和「/foo/」視為不同。否則,路由器會將「/foo」和「/foo/」視為相同。 注意:子應用程式會繼承此設定的值。 |
不適用(未定義) |
|
數字 | 要移除以存取子網域的主機點分部分數。 | 2 |
|
變數 |
表示應用程式位於面向使用者的代理程式之後,且要使用 啟用時,Express 會嘗試判斷透過面向使用者的代理程式或一系列代理程式連線的用戶端 IP 位址。然後,`req.ips` 屬性會包含用戶端連線的 IP 位址陣列。若要啟用,請使用 信任代理選項表格 中所述的值。
注意:子應用程式會繼承此設定的值,即使它有預設值。 |
|
|
字串或陣列 | 應用程式檢視的目錄或目錄陣列。如果是陣列,檢視會按照它們在陣列中出現的順序進行查詢。 |
|
|
布林值 | 啟用檢視範本編譯快取。 注意:子應用程式不會繼承此設定在生產環境中的值(當 `NODE_ENV` 為「生產」)。 |
在生產環境中為 |
|
字串 | 省略時要使用的預設引擎擴充功能。
注意:子應用程式會繼承此設定的值。 |
不適用(未定義) |
|
布林值 | 啟用「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!')
})
路徑範例
下表提供了一些用於安裝中間件的有效 path
值的簡單範例。
類型 | 範例 |
---|---|
路徑 |
這將比對以
|
路徑模式 |
這將比對以
這將比對以
這將比對以
這將比對以
|
正規表示法 |
這將比對以
|
陣列 |
這將比對以
|
中間件回呼函式範例
下表提供了一些簡單的中間件函式範例,可用作 app.use()
、app.METHOD()
和 app.all()
的 callback
參數。即使範例是針對 app.use()
,它們也適用於 app.use()
、app.METHOD()
和 app.all()
。
用法 | 範例 |
---|---|
單一中間件 |
你可以在本地定義和安裝中間件函式。
路由器是有效的中間件。
Express 應用程式是有效的中間件。
|
一系列中間件 |
您可以在同一個 mount 路徑中指定多個中間件函式。
|
陣列 |
使用陣列以邏輯方式將中間件分組。
|
組合 |
您可以組合上述所有中間件安裝方式。
|
以下是使用 express.static 中間件於 Express 應用程式中的一些範例。
從應用程式目錄中的「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 標頭衍生的主機名稱。
當 trust proxy
設定 未評估為 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
在 middleware 和路由物件中皆可用,而且是 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 處理函式。變更只適用於路由路徑中已定義的 參數。
在 middleware 或路由處理函式中對 req.params
物件所做的任何變更都會重設。
注意:Express 會自動解碼 req.params
中的值(使用 decodeURIComponent
)。
req.path
包含請求 URL 的路徑部分。
// example.com/users?sort=desc
console.dir(req.path)
// => '/users'
從 middleware 呼叫時,掛載點不會包含在 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
})
}
回應
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([filename])
將 HTTP 回應 Content-Disposition
標頭欄位設定為「attachment」。如果給定 filename
,則它會透過 res.type()
根據副檔名設定 Content-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(name, value [, options])
將 Cookie name
設定為 value
。value
參數可以是轉換為 JSON 的字串或物件。
options
參數是一個物件,可以有下列屬性。
屬性 | 類型 | 說明 |
---|---|---|
domain |
字串 | Cookie 的網域名稱。預設為應用程式的網域名稱。 |
encode |
函式 | 用於 Cookie 值編碼的同步函式。預設為 encodeURIComponent 。 |
expires |
日期 | Cookie 在 GMT 中的到期日。如果未指定或設定為 0,則會建立一個會話 Cookie。 |
httpOnly |
布林值 | 標記 Cookie,使其只能由網路伺服器存取。 |
maxAge |
數字 | 設定相對於目前時間的到期時間(以毫秒為單位)的便利選項。 |
path |
字串 | Cookie 的路徑。預設為「/」。 |
partitioned |
布林值 | 表示應使用分區儲存空間來儲存 Cookie。請參閱 Cookies Having Independent Partitioned State (CHIPS) 以取得更多詳細資訊。 |
優先權 |
字串 | 「優先權」Set-Cookie 屬性的值。 |
安全 |
布林值 | 標記 cookie 僅與 HTTPS 一起使用。 |
已簽署 |
布林值 | 指出是否應簽署 cookie。 |
同網站 |
布林值或字串 | 「同網站」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。只需將 signed
選項設定為 true
即可。然後,res.cookie()
將使用傳遞給 cookieParser(secret)
的機密來簽署值。
res.cookie('name', 'tobi', { signed: true })
稍後,您可以透過 req.signedCookie 物件存取這個值。
res.clearCookie(name [, options])
清除由 name
指定的 cookie。有關 options
物件的詳細資訊,請參閱 res.cookie()。
Web 瀏覽器和其他相容的用戶端僅會在指定的 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
引數包含使用者輸入,則建構 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+ |
標頭 |
包含要與檔案一起提供的 HTTP 標頭的物件。標頭 Content-Disposition 會被 filename 參數覆寫。 |
4.16+ | |
dotfiles |
提供 dotfiles 的選項。可能的值為「允許」、「拒絕」、「忽略」。 | 「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
重新導向會將請求重新導向回 referer,當 referer 遺失時預設為 /
。
res.redirect('back')
res.render(view [, locals] [, callback])
呈現 view
並將呈現的 HTML 字串傳送給客戶端。選用參數
locals
,一個物件,其屬性定義檢視的局部變數。callback
,一個回呼函式。如果提供,則此方法會同時傳回可能的錯誤和呈現的字串,但不會執行自動化的回應。當錯誤發生時,此方法會在內部呼叫next(err)
。
view
參數是一個字串,是待呈現檢視檔案的檔案路徑。這可以是絕對路徑,或是相對於 views
設定的路徑。如果路徑不包含檔案副檔名,則 view engine
設定會決定檔案副檔名。如果路徑包含檔案副檔名,則 Express 會載入指定範本引擎的模組(透過 require()
),並使用載入模組的 __express
函式來呈現它。
如需更多資訊,請參閱 使用範本引擎與 Express。
檢視
參數會執行檔案系統作業,例如從磁碟讀取檔案和評估 Node.js 模組,因此出於安全考量,不應包含來自最終使用者的輸入。
locals
物件由檢視引擎用於呈現回應。物件金鑰可能特別敏感,不應包含使用者控制的輸入,因為它可能會影響檢視引擎的運作或提供跨網站指令碼路徑。請參閱所用檢視引擎的文件,以了解其他考量因素。
區域變數 快取
啟用檢視快取。將其設定為 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
物件、字串
、物件、布林值
或 陣列
。例如
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>'))
當參數是 字串
時,此方法會將 Content-Type
設定為「text/html」
res.send('<p>some html</p>')
當參數是 陣列
或 物件
時,Express 會回應 JSON 表示法
res.send({ user: 'tobi' })
res.send([1, 2, 3])
res.sendFile(path [, options] [, fn])
res.sendFile()
受 Express v4.8.0 以上版本支援。
傳輸給定 路徑
的檔案。根據檔名副檔名設定 Content-Type
回應 HTTP 標頭欄位。除非在選項物件中設定 根目錄
選項,否則 路徑
必須是檔案的絕對路徑。
此 API 提供存取執行中檔案系統的資料。請確保 (a) 構建 路徑
參數成絕對路徑的方式,如果它包含使用者輸入,則安全,或 (b) 將 根目錄
選項設定為目錄的絕對路徑,以包含在其中存取。
提供 根目錄
選項時,允許 路徑
參數為相對路徑,包括包含 ..
。Express 會驗證提供為 路徑
的相對路徑會在給定的 根目錄
選項中解析。
下表提供 options
參數的詳細資訊。
屬性 | 說明 | 預設值 | 可用性 |
---|---|---|---|
maxAge |
以毫秒或 ms 格式 的字串設定 Cache-Control 標頭的 max-age 屬性 |
0 | |
root |
相對檔案名稱的根目錄。 | ||
lastModified |
將 Last-Modified 標頭設定為作業系統上檔案的最後修改日期。設定為 false 以停用。 |
已啟用 | 4.9.0+ |
標頭 |
包含要與檔案一起提供的 HTTP 標頭的物件。 | ||
dotfiles |
提供 dotfiles 的選項。可能的值為「允許」、「拒絕」、「忽略」。 | 「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)
當 res.statusCode
設定為無效的 HTTP 狀態碼(在 100
到 599
範圍之外)時,某些版本的 Node.js 會擲回例外。請查閱正在使用的 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
的確切值,否則假設它為檔案副檔名,並使用 express.static.mime.lookup()
方法在對應中查詢 MIME 類型。
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
物件是中介軟體和路由的獨立執行個體。您可以將它視為一個「迷你應用程式」,僅能執行中介軟體和路由功能。每個 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)
將回呼觸發器加入路徑參數,其中 name
是參數的名稱,而 callback
是回呼函式。儘管技術上 name
是選用的,但從 Express v4.11.0 開始,不使用此方法會被視為已棄用(請見下方)。
回呼函式的參數為
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'))
}
})
})
Param 回呼函式是定義在路由器中的區域變數。它們不會被掛載的應用程式或路由器繼承。因此,定義在 router
上的 param 回呼函式只會由定義在 router
路由上的路由參數觸發。
Param 回呼函式在請求-回應循環中只會被呼叫一次,即使參數在多個路由中相符,如下列範例所示。
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()
現在會接受一個名稱和一個數字,而不是接受一個名稱和一個回呼函式。
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)
使用指定的 middleware 函數或函數,並搭配選用的掛載路徑 path
,預設為「/」。
此方法類似於 app.use()。以下說明一個簡單的範例和使用案例。請參閱 app.use() 以取得更多資訊。
Middleware 就如同水管:要求從定義的第一個 middleware 函數開始,並沿著 middleware 堆疊「向下」處理與其相符的每個路徑。
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)
「掛載」路徑會被移除,且 middleware 函數不會看到它。此功能的主要效果是,掛載的 middleware 函數可以不受其「前置」路徑名稱影響而運作,且不需變更程式碼。
使用 router.use()
定義 middleware 的順序非常重要。它們會依序呼叫,因此順序會定義 middleware 的優先順序。例如,記錄器通常會是你使用的第一個 middleware,以便記錄每個要求。
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()
之後定義的路由和 middleware。你只要將對 express.static()
的呼叫移到最上面,在加入記錄器 middleware 之前
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()
方法也支援命名參數,以便其他路由器的掛載點可以受益於使用命名參數進行預先載入。
注意:雖然這些 middleware 函數是透過特定路由器加入的,但何時執行它們是由它們所附加的路徑(而非路由器)決定的。因此,透過一個路由器加入的 middleware 可能會為其他路由器執行,如果其路由相符。例如,此程式碼顯示兩個不同的路由器掛載在同一路徑上
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)
即使驗證 middleware 是透過 authRouter
加入的,它也會在 openRouter
定義的路由上執行,因為兩個路由器都掛載在 /users
上。若要避免這種行為,請為每個路由器使用不同的路徑。