Express 3.x 不再維護
3.x 中已知和未知的安全和效能問題自上次更新(2015 年 8 月 1 日)以來尚未解決。強烈建議使用最新版本的 Express。
3.x API
express()
建立 Express 應用程式。express()
函式是 express 模組匯出的頂層函式。
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('hello world')
})
app.listen(3000)
應用程式
app.set(name, value)
將設定 name
指定給 value
。
app.set('title', 'My Site')
app.get('title')
// => "My Site"
app.get(name)
取得設定 name
的值。
app.get('title')
// => undefined
app.set('title', 'My Site')
app.get('title')
// => "My Site"
app.enable(name)
將設定 name
設為 true
。
app.enable('trust proxy')
app.get('trust proxy')
// => true
app.disable(name)
將設定 name
設為 false
。
app.disable('trust proxy')
app.get('trust proxy')
// => false
app.enabled(name)
檢查設定 name
是否已啟用。
app.enabled('trust proxy')
// => false
app.enable('trust proxy')
app.enabled('trust proxy')
// => true
app.disabled(name)
檢查設定 name
是否已停用。
app.disabled('trust proxy')
// => true
app.enable('trust proxy')
app.disabled('trust proxy')
// => false
app.configure([env], callback)
當 env
與 app.get('env')
,也就是 process.env.NODE_ENV
相符時,有條件地呼叫 callback
。此方法基於傳統原因而保留,實際上是 if
陳述式,如下列程式片段所示。若要使用 app.set()
和其他組態方法,不需要這些函式。
// all environments
app.configure(function () {
app.set('title', 'My Application')
})
// development only
app.configure('development', function () {
app.set('db uri', 'localhost/dev')
})
// production only
app.configure('production', function () {
app.set('db uri', 'n.n.n.n/prod')
})
實際上是對下列內容的語法糖
// all environments
app.set('title', 'My Application')
// development only
if (app.get('env') === 'development') {
app.set('db uri', 'localhost/dev')
}
// production only
if (app.get('env') === 'production') {
app.set('db uri', 'n.n.n.n/prod')
}
app.use([path], function)
使用指定的 middleware function
,並可選擇掛載 path
,預設為「/」。
var express = require('express')
var app = express()
// simple logger
app.use(function (req, res, next) {
console.log('%s %s', req.method, req.url)
next()
})
// respond
app.use(function (req, res, next) {
res.send('Hello World')
})
app.listen(3000)
「掛載」路徑會被移除,而且 middleware function
看不到 該路徑。此功能的主要效果是,已掛載的 middleware 可以運作,而不管其「前置」路徑名稱為何,都不需要變更程式碼。
路由會比對緊接在路徑之後、且包含「/
」或「.
」的任何路徑。例如:app.use('/apple', ...)
會比對 /apple、/apple/images、/apple/images/news、/apple.html、/apple.html.txt 等。
以下是一個具體範例,採用使用 express.static()
middleware 在 ./public 中提供檔案的典型使用案例
// GET /javascripts/jquery.js
// GET /style.css
// GET /favicon.ico
app.use(express.static(path.join(__dirname, 'public')))
假設您想要使用「/static」為所有靜態檔案加上前置字元,您可以使用「掛載」功能來支援此功能。除非 req.url
包含此前置字元,否則不會呼叫已掛載的 middleware 函式,而當函式被呼叫時,會移除前置字元。這只會影響此函式,後續 middleware 會看到包含「/static」的 req.url
,除非它們也已掛載。
// GET /static/javascripts/jquery.js
// GET /static/style.css
// GET /static/favicon.ico
app.use('/static', express.static(path.join(__dirname, 'public')))
使用 app.use()
「定義」middleware 的順序非常重要,它們會依序呼叫,因此這會定義 middleware 的優先順序。例如,通常 express.logger()
會是您會使用的第一個 middleware,用來記錄每個要求
app.use(express.logger())
app.use(express.static(path.join(__dirname, 'public')))
app.use(function (req, res) {
res.send('Hello')
})
現在假設您想要忽略靜態檔案的記錄請求,但繼續記錄在 logger()
之後定義的路由和中間件,您只需將 static()
移到上面
app.use(express.static(path.join(__dirname, 'public')))
app.use(express.logger())
app.use(function (req, res) {
res.send('Hello')
})
另一個具體範例會是從多個目錄提供檔案,優先於其他目錄的「./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')))
設定
提供下列設定來變更 Express 的行為
env
環境模式,預設為 process.env.NODE_ENV 或「development」trust proxy
啟用反向代理支援,預設為停用jsonp callback name
變更預設的回呼名稱 ?callback=json replacer
JSON replacer 回呼,預設為 nulljson spaces
JSON 回應的格式化空白,在開發環境中預設為 2,在生產環境中預設為 0case sensitive routing
啟用大小寫敏感性,預設為停用,將「/Foo」和「/foo」視為相同strict routing
啟用嚴格路由,預設情況下,路由器將「/foo」和「/foo/」視為相同view cache
啟用檢視範本編譯快取,在生產環境中預設為啟用view engine
省略時要使用的預設引擎擴充功能views
檢視目錄路徑,預設為「process.cwd() + ‘/views’」
app.engine(ext, callback)
將指定的範本引擎 callback
註冊為 ext
預設會根據檔案擴充功能 require()
引擎。例如,如果您嘗試呈現「foo.jade」檔案,Express 會在內部呼叫下列內容,並在後續呼叫中快取 require()
以提升效能。
app.engine('jade', require('jade').__express)
對於未提供 .__express
的引擎,或如果你希望將不同的副檔名「對應」到範本引擎,你可以使用此方法。例如將 EJS 範本引擎對應到「.html」檔案
app.engine('html', require('ejs').renderFile)
在此情況下,EJS 提供一個 .renderFile()
方法,其簽章與 Express 預期的相同:(path, options, callback)
,但請注意,它在內部將此方法別名為 ejs.__express
,因此如果你使用「.ejs」副檔名,則不需要執行任何操作。
有些範本引擎不遵循此慣例,consolidate.js 函式庫是用來將所有節點的熱門範本引擎對應到此慣例,進而讓它們可以在 Express 中無縫運作。
var engines = require('consolidate')
app.engine('haml', engines.haml)
app.engine('html', engines.hogan)
app.param([name], callback)
將邏輯對應到路由參數。例如,當路由路徑中出現 :user
時,你可以將使用者載入邏輯對應到自動提供 req.user
給路由,或對參數輸入執行驗證。
以下程式碼片段說明 callback
與中間件非常類似,因此支援非同步作業,但提供參數的附加值,在此稱為 id
。然後嘗試載入使用者,指定 req.user
,否則將錯誤傳遞給 next(err)
。
app.param('user', function (req, res, next, id) {
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
,在這種情況下,你有機會變更 app.param()
API。例如,express-params 定義下列 callback,它允許你將參數限制為特定的正規表示式。
此範例稍微進階一點,檢查第二個引數是否為正規表示式,傳回的 callback 與「使用者」參數範例非常類似。
app.param(function (name, fn) {
if (fn instanceof RegExp) {
return function (req, res, next, val) {
var captures
if ((captures = fn.exec(String(val)))) {
req.params[name] = captures
next()
} else {
next('route')
}
}
}
})
現在可以使用此方法有效驗證參數,或將它們剖析以提供擷取群組
app.param('id', /^\d+$/)
app.get('/user/:id', function (req, res) {
res.send('user ' + req.params.id)
})
app.param('range', /^(\w+)\.\.(\w+)?$/)
app.get('/range/:range', function (req, res) {
var range = req.params.range
res.send('from ' + range[1] + ' to ' + range[2])
})
app.VERB(路徑, [回呼...], 回呼)
app.VERB()
方法提供 Express 中的路由功能,其中 VERB 是 HTTP 動詞之一,例如 app.post()
。可以提供多個回呼,所有回呼都以相同的方式處理,且行為就像中間件,只有一個例外,這些回呼可能會呼叫 next('route')
以略過其餘的路由回呼。此機制可用於對路由執行前置條件,然後在沒有理由繼續執行已比對的路由時,將控制權傳遞給後續路由。
下列程式片段說明最簡單的路由定義。Express 會將路徑字串轉換為正規表示式,並在內部用於比對傳入的請求。執行這些比對時不會考量查詢字串,例如「GET /」會比對下列路由,而「GET /?name=tobi」也會比對。
app.get('/', function (req, res) {
res.send('hello world')
})
也可以使用正規表示式,如果您有非常具體的限制,這會很有用,例如下列範例會比對「GET /commits/71dbb9c」以及「GET /commits/71dbb9c..4c084f9」。
app.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function (req, res) {
var from = req.params[0]
var to = req.params[1] || 'HEAD'
res.send('commit range ' + from + '..' + to)
})
也可以傳遞多個回呼,這對於重複使用載入資源、執行驗證等中間件很有用。
app.get('/user/:id', user.load, function () {
// ...
})
這些回呼也可以在陣列中傳遞,這些陣列在傳遞時會直接扁平化
var middleware = [loadForum, loadThread]
app.get('/forum/:fid/thread/:tid', middleware, function () {
// ...
})
app.post('/forum/:fid/thread/:tid', middleware, function () {
// ...
})
app.all(路徑, [回呼...], 回呼)
此方法的功能就像 app.VERB()
方法,但它會比對所有 HTTP 動詞。
此方法對於特定路徑前綴或任意比對的「全域」邏輯對應非常有用。例如,如果您將下列路由置於所有其他路由定義的最上方,則從該點開始的所有路由都將需要驗證,並自動載入使用者。請記住,這些回呼函數不必作為端點,loadUser
可以執行一項任務,然後 next()
繼續比對後續路由。
app.all('*', requireAuthentication, loadUser)
或等效於
app.all('*', requireAuthentication)
app.all('*', loadUser)
另一個此功能的絕佳範例是白名單「全域」功能。這裡的範例與之前非常類似,但僅限制以「/api」為前綴的路徑
app.all('/api/*', requireAuthentication)
app.locals
應用程式本機變數會提供給應用程式內所呈現的所有範本。這對於提供範本的輔助函數以及應用程式層級資料非常有用。
app.locals.title = 'My App'
app.locals.strftime = require('strftime')
app.locals
物件是一個 JavaScript 函數
,當以一個物件呼叫時,會將屬性合併到自身,提供一個簡單的方式來將現有物件公開為本機變數。
app.locals({
title: 'My App',
phone: '1-250-858-9990',
email: 'me@myapp.com'
})
console.log(app.locals.title)
// => 'My App'
console.log(app.locals.email)
// => 'me@myapp.com'
由於 app.locals
物件最終是一個 JavaScript 函數物件,因此您不得重複使用現有 (原生) 命名屬性作為您自己的變數名稱,例如 name, apply, bind, call, arguments, length, constructor
。
app.locals({ name: 'My App' })
console.log(app.locals.name)
// => return 'app.locals' in place of 'My App' (app.locals is a Function !)
// => if name's variable is used in a template, a ReferenceError will be returned.
可以在許多規格中找到原生命名屬性的完整清單。 JavaScript 規格 介紹了原始屬性,其中一些仍由現代引擎識別,而 EcmaScript 規格 接著建立在它上面,並標準化屬性集,新增新的屬性並移除不建議使用的屬性。如果您有興趣,請查看函數和物件的屬性。
預設情況下,Express 僅公開一個應用程式層級本機變數,settings
。
app.set('title', 'My App')
// use settings.title in a view
app.render(view, [options], callback)
使用回呼函式產生一個 view
,並回應產生的字串。這是 res.render()
的應用程式層級變體,其他行為方式相同。
app.render('email', function (err, html) {
// ...
})
app.render('email', { name: 'Tobi' }, function (err, html) {
// ...
})
app.routes
app.routes
物件包含所有已定義路由,並由相關的 HTTP 動詞對應。此物件可用於內省功能,例如 Express 內部不只使用它來進行路由,還會提供預設
除非使用 app.options()
,否則會產生行為。您的應用程式或架構也可以透過從此物件中移除路由來移除路由。
console.log(app.routes)
的輸出
{ get:
[ { path: '/',
method: 'get',
callbacks: [Object],
keys: [],
regexp: /^\/\/?$/i },
{ path: '/user/:id',
method: 'get',
callbacks: [Object],
keys: [{ name: 'id', optional: false }],
regexp: /^\/user\/(?:([^\/]+?))\/?$/i } ],
delete:
[ { path: '/user/:id',
method: 'delete',
callbacks: [Object],
keys: [Object],
regexp: /^\/user\/(?:([^\/]+?))\/?$/i } ] }
app.listen()
在指定的 host 和埠上繫結並偵聽連線,此方法與 node 的 http.Server#listen() 相同。
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()
方法只是一個方便的方法,定義為,如果您想要使用 HTTPS 或同時提供,請使用上述技巧。
app.listen = function () {
var server = http.createServer(this)
return server.listen.apply(server, arguments)
}
要求
req
物件是 Node 自身要求物件的加強版本,並支援所有 內建欄位和方法。
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.query
此屬性為包含已剖析查詢字串的物件,預設為 {}
。
// GET /search?q=tobi+ferret
console.dir(req.query.q)
// => 'tobi ferret'
// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
console.dir(req.query.order)
// => 'desc'
console.dir(req.query.shoe.color)
// => 'blue'
console.dir(req.query.shoe.type)
// => 'converse'
req.body
此屬性為包含已剖析要求主體的物件。此功能由 bodyParser()
中介軟體提供,但其他主體剖析中介軟體也可能遵循此慣例。當使用 bodyParser()
時,此屬性預設為 {}
。
// POST user[name]=tobi&user[email]=tobi@learnboost.com
console.log(req.body.user.name)
// => "tobi"
console.log(req.body.user.email)
// => "tobi@learnboost.com"
// POST { "name": "tobi" }
console.log(req.body.name)
// => "tobi"
req.files
此屬性為已上傳檔案的物件。此功能由 bodyParser()
中介軟體提供,但其他主體剖析中介軟體也可能遵循此慣例。當使用 bodyParser()
時,此屬性預設為 {}
。
例如,如果一個 檔案 欄位命名為「image」,且已上傳一個檔案,則 req.files.image
將包含下列 File
物件
{ size: 74643,
path: '/tmp/8ef9c52abe857867fd0a4e9a819d1876',
name: 'edge.png',
type: 'image/png',
hash: false,
lastModifiedDate: Thu Aug 09 2012 20:07:51 GMT-0700 (PDT),
_writeStream:
{ path: '/tmp/8ef9c52abe857867fd0a4e9a819d1876',
fd: 13,
writable: false,
flags: 'w',
encoding: 'binary',
mode: 438,
bytesWritten: 74643,
busy: false,
_queue: [],
_open: [Function],
drainable: true },
length: [Getter],
filename: [Getter],
mime: [Getter] }
bodyParser()
中介軟體在內部使用 node-formidable 模組,並接受相同的選項。一個範例是 keepExtensions
formidable 選項,預設為 false,在本例中會提供不含「.png」副檔名的檔名「/tmp/8ef9c52abe857867fd0a4e9a819d1876」。若要啟用此選項和其他選項,您可以將它們傳遞給 bodyParser()
app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/my/files' }))
req.param(name)
在存在時傳回參數 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
為清楚起見,應優先直接存取 req.body
、req.params
和 req.query
,除非您確實接受來自每個物件的輸入。
req.route
目前相符的 Route
,包含多個屬性,例如路由的原始路徑字串、產生的正規表示法等。
app.get('/user/:id?', function (req, res) {
console.dir(req.route)
})
前一個程式片段的範例輸出
{ path: '/user/:id?',
method: 'get',
callbacks: [ [Function] ],
keys: [ { name: 'id', optional: true } ],
regexp: /^\/user(?:\/([^\/]+?))?\/?$/i,
params: [ id: '12' ] }
req.cookies
此物件需要 cookieParser()
中介軟體才能使用。它包含使用者代理程式傳送的 Cookie。如果未傳送任何 Cookie,則預設為 {}
。
// Cookie: name=tj
console.log(req.cookies.name)
// => "tj"
req.signedCookies
此物件需要 cookieParser(secret)
中介軟體才能使用。它包含使用者代理程式傳送的已簽署 cookie,未簽署且已準備好使用。已簽署的 cookie 會駐留在不同的物件中,以顯示開發人員的意圖;否則,惡意攻擊可能會放置在 req.cookie
值上(很容易偽造)。請注意,簽署 cookie 並不會讓它「隱藏」或加密;這只是防止竄改(因為用於簽署的密碼是私密的)。如果未傳送已簽署的 cookie,它會預設為 {}
。
// Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3
console.dir(req.signedCookies.user)
// => 'tobi'
req.get(field)
取得不分大小寫的請求標頭 field
。「Referrer」和「Referer」欄位可以互換。
req.get('Content-Type')
// => "text/plain"
req.get('content-type')
// => "text/plain"
req.get('Something')
// => undefined
p 別名為 req.header(field)
。
req.accepts(types)
檢查指定的 types
是否可接受,如果為真,則傳回最佳配對,否則為 undefined
- 在這種情況下,您應該回應 406「不可接受」。
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')
// => undefined
// Accept: text/*;q=.5, application/json
req.accepts(['html', 'json'])
req.accepts('html, json')
// => "json"
req.accepted
傳回一個已接受的媒體類型陣列,從最高品質到最低品質排序。
[ { value: 'application/json',
quality: 1,
type: 'application',
subtype: 'json' },
{ value: 'text/html',
quality: 0.5,
type: 'text',
subtype: 'html' } ]
req.is(type)
檢查傳入的請求是否包含「Content-Type」標頭欄位,以及它是否與給定的 MIME type
相符。
// With Content-Type: text/html; charset=utf-8
req.is('html')
req.is('text/html')
req.is('text/*')
// => true
// When Content-Type is application/json
req.is('json')
req.is('application/json')
req.is('application/*')
// => true
req.is('html')
// => false
req.ip
傳回遠端位址,或當「信任代理程式」已啟用時 - 上游位址。
console.dir(req.ip)
// => '127.0.0.1'
req.ips
當「信任代理程式」為 true
時,剖析「X-Forwarded-For」IP 位址清單並傳回一個陣列,否則會傳回一個空陣列。
例如,如果值為「client, proxy1, proxy2」,您會收到陣列 ["client", "proxy1", "proxy2"]
,其中「proxy2」是最下游的。
req.path
傳回請求 URL 路徑名稱。
// example.com/users?sort=desc
console.dir(req.path)
// => '/users'
req.host
從「Host」標頭欄位傳回主機名稱(不含埠號)。
// Host: "example.com:3000"
console.dir(req.host)
// => 'example.com'
req.fresh
檢查請求是否為最新 - 也稱為 Last-Modified 和/或 ETag 仍相符,表示資源為「最新」。
console.dir(req.fresh)
// => true
req.stale
檢查請求是否為過期 - 也稱為 Last-Modified 和/或 ETag 不相符,表示資源為「過期」。
console.dir(req.stale)
// => true
req.xhr
檢查請求是否已發出,且「X-Requested-With」標頭欄位設定為「XMLHttpRequest」(jQuery 等)。
console.dir(req.xhr)
// => true
req.protocol
當使用 TLS 請求時,傳回通訊協定字串「http」或「https」。當啟用「信任代理」設定時,將會信任「X-Forwarded-Proto」標頭欄位。如果您在後端執行提供 https 給您的反向代理程式,則可能會啟用此設定。
console.dir(req.protocol)
// => 'http'
req.secure
檢查是否已建立 TLS 連線。這是
console.dir(req.protocol === 'https')
// => true
req.subdomains
將子網域傳回為陣列。
// Host: "tobi.ferrets.example.com"
console.dir(req.subdomains)
// => ['ferrets', 'tobi']
req.originalUrl
此屬性很像 req.url
,但它會保留原始請求網址,讓您能自由改寫 req.url
以供內部路由使用。例如,app.use() 的「掛載」功能會改寫 req.url
以移除掛載點。
// GET /search?q=something
console.log(req.originalUrl)
// => "/search?q=something"
req.acceptedLanguages
傳回已接受語言的陣列,從最高品質到最低品質排序。
Accept-Language: en;q=.5, en-us
// => ['en-us', 'en']
req.acceptedCharsets
傳回已接受字元集的陣列,從最高品質到最低品質排序。
Accept-Charset: iso-8859-5;q=.2, unicode-1-1;q=0.8
// => ['unicode-1-1', 'iso-8859-5']
req.acceptsCharset(charset)
檢查指定的 charset
是否可接受。
req.acceptsLanguage(lang)
檢查指定的 lang
是否可接受。
req.res
此屬性持有與此請求物件相關的 回應物件 的參考。
回應
res
物件是 Node 自身回應物件的加強版,並支援所有 內建欄位和方法。
res.status(code)
Node 的 res.statusCode=
的可串接別名。
res.status(404).sendfile('path/to/404.png')
res.set(欄位, [值])
將標頭 欄位
設定為 值
,或傳遞物件以一次設定多個欄位。
res.set('Content-Type', 'text/plain')
res.set({
'Content-Type': 'text/plain',
'Content-Length': '123',
ETag: '12345'
})
別名為 res.header(欄位, [值])
。
res.get(欄位)
取得不分大小寫的回應標頭 欄位
。
res.get('Content-Type')
// => "text/plain"
res.cookie(名稱, 值, [選項])
將 cookie 名稱
設定為 值
,可以是轉換為 JSON 的字串或物件。路徑
選項預設為「/」。
res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true })
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true })
maxAge
選項是方便的選項,用於設定相對於目前時間的「過期時間」,單位為毫秒。以下範例等同於前一個範例。
res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
可以傳遞物件,然後序列化為 JSON,bodyParser()
中介軟體會自動解析。
res.cookie('cart', { items: [1, 2, 3] })
res.cookie('cart', { items: [1, 2, 3] }, { maxAge: 900000 })
此方法也支援已簽署的 cookie。只要傳遞 已簽署
選項即可。當給定 res.cookie()
時,將使用傳遞給 express.cookieParser(秘密)
的秘密來簽署值。
res.cookie('name', 'tobi', { signed: true })
稍後可以透過 req.signedCookie 物件存取此值。
res.clearCookie(名稱, [選項])
清除 cookie 名稱
。路徑
選項預設為「/」。
res.cookie('name', 'tobi', { path: '/admin' })
res.clearCookie('name', { path: '/admin' })
res.redirect([狀態], 網址)
重新導向到指定的 網址
,選用的 狀態
碼預設為 302「已找到」。
res.redirect('/foo/bar')
res.redirect('http://example.com')
res.redirect(301, 'http://example.com')
res.redirect('../login')
Express 支援幾種重新導向形式,首先是完全限定的 URI,用於重新導向到不同的網站
res.redirect('http://google.com')
第二種形式是路徑名稱相對重新導向,例如如果您在 http://example.com/admin/post/new
,以下重新導向到 /admin
會將您帶到 http://example.com/admin
res.redirect('/admin')
下一個重新導向是相對於應用程式的 掛載
點。例如,如果您有一個掛載在 /blog
的部落格應用程式,理想情況下它不知道它掛載在哪裡,因此重新導向 /admin/post/new
只會提供給您 http://example.com/admin/post/new
,以下掛載相對重新導向會提供給您 http://example.com/blog/admin/post/new
res.redirect('admin/post/new')
路徑名稱相對重定向也是可能的。如果您在http://example.com/admin/post/new
,以下重定向會將您帶到http//example.com/admin/post
res.redirect('..')
最後一個特殊情況是back
重定向,重定向回參考者 (或引導者),在遺失時預設為/
。
res.redirect('back')
res.location
設定位置標頭。
res.location('/foo/bar')
res.location('foo/bar')
res.location('http://example.com')
res.location('../login')
res.location('back')
您可以使用與res.redirect()
中相同的urls
類型。
例如,如果您的應用程式掛載在/blog
,以下會將location
標頭設定為/blog/admin
res.location('admin')
res.charset
指定字元集。預設為“utf-8”。
res.charset = 'value'
res.send('<p>some html</p>')
// => Content-Type: text/html; charset=value
res.send([body|status], [body])
傳送回應。
res.send(Buffer.from('whoop'))
res.send({ some: 'json' })
res.send('<p>some html</p>')
res.send(404, 'Sorry, we cannot find that!')
res.send(500, { error: 'something blew up' })
res.send(200)
此方法執行許多對簡單非串流回應有用的工作,例如自動指定內容長度,除非先前已定義,並提供自動HEAD和 HTTP 快取新鮮度支援。
當給定Buffer
時,內容類型會設定為“application/octet-stream”,除非先前已定義,如下所示
res.set('Content-Type', 'text/html')
res.send(Buffer.from('<p>some html</p>'))
當給定String
時,內容類型預設設定為“text/html”
res.send('<p>some html</p>')
當給定Array
或Object
時,Express 會回應 JSON 表示。
res.send({ user: 'tobi' })
res.send([1, 2, 3])
最後,當給定Number
而沒有任何先前提到的主體時,會為您指定回應主體字串。例如,200 會回應文字“OK”,404 會回應“Not Found”,依此類推。
res.send(200)
res.send(404)
res.send(500)
res.json([status|body], [body])
傳送 JSON 回應。當傳遞物件或陣列時,此方法與res.send()
相同,但可用於非物件的明確 JSON 轉換 (null、未定義等),儘管這些在技術上不是有效的 JSON。
res.json(null)
res.json({ user: 'tobi' })
res.json(500, { error: 'message' })
res.jsonp([status|body], [body])
傳送具有 JSONP 支援的 JSON 回應。此方法與res.json()
相同,但選擇加入 JSONP 回呼支援。
res.jsonp(null)
// => null
res.jsonp({ user: 'tobi' })
// => { "user": "tobi" }
res.jsonp(500, { error: 'message' })
// => { "error": "message" }
預設情況下,JSONP 回呼名稱只是callback
,但您可以使用jsonp 回呼名稱設定來變更它。以下是使用相同程式碼的一些 JSONP 回應範例
// ?callback=foo
res.jsonp({ user: 'tobi' })
// => foo({ "user": "tobi" })
app.set('jsonp callback name', 'cb')
// ?cb=foo
res.jsonp(500, { error: 'message' })
// => foo({ "error": "message" })
res.type(type)
將 Content-Type 設定為 type
的 mime 查詢,或當出現「/」時,Content-Type 僅設定為此文字值。
res.type('.html')
res.type('html')
res.type('json')
res.type('application/json')
res.type('png')
p 別名為 res.contentType(type)
。
res.format(object)
當存在時,對要求的 Accept 標頭欄位執行內容協商。此方法使用 req.accepted
,一個依品質值排序的可接受類型陣列,否則會呼叫第一個回呼。當沒有執行配對時,伺服器會回應 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' })
}
})
除了正規化的 MIME 類型外,您也可以使用對應到這些類型的 extname,提供一個簡潔許多的實作
res.format({
text: function () {
res.send('hey')
},
html: function () {
res.send('<p>hey</p>')
},
json: function () {
res.send({ message: 'hey' })
}
})
res.attachment([filename])
將 Content-Disposition 標頭欄位設定為「attachment」。如果給定 filename
,則 Content-Type 會自動根據 extname 透過 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.sendfile(path, [options], [fn]])
傳輸給定 path
的檔案。
根據檔案名稱的副檔名自動預設 Content-Type 回應標頭欄位。當傳輸完成或發生錯誤時,會呼叫回呼 fn(err)
。
選項
maxAge
以毫秒為單位,預設為 0root
相對檔案名稱的根目錄
此方法提供細緻的檔案提供支援,如下列範例所示
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.send(403, 'Sorry! you cant see that.')
}
})
})
res.download(path, [filename], [fn])
將檔案傳輸至 路徑
作為「附件」,瀏覽器通常會提示使用者下載。Content-Disposition 的「filename=」參數,也就是會顯示在瀏覽器對話框中的參數,預設會設定為 路徑
,不過你可以提供替代的 檔名
。
當發生錯誤或傳輸完成時,會呼叫選用的回呼 fn
。此方法使用 res.sendfile() 傳輸檔案。
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, keep in mind the response may be partially-sent
// so check res.headerSent
} else {
// decrement a download credit etc
}
})
res.links(links)
加入指定的 連結
以填入「連結」回應標頭欄位。
res.links({
next: 'http://api.example.com/users?page=2',
last: 'http://api.example.com/users?page=5'
})
p 產生
Link: <http://api.example.com/users?page=2> rel="next",
<http://api.example.com/users?page=5> rel="last"
res.locals
回應的區域變數會限定在要求中,因此只有在該要求 / 回應週期中呈現的檢視才能使用,如果有任何檢視的話。否則,此 API 與 app.locals 相同。
此物件對於公開要求層級資訊(例如要求路徑名稱、經過驗證的使用者、使用者設定等)很有用。
app.use(function (req, res, next) {
res.locals.user = req.user
res.locals.authenticated = !req.user.anonymous
next()
})
res.render(view, [locals], callback)
使用回呼呈現 檢視
,回應呈現的字串。當發生錯誤時,會在內部呼叫 next(err)
。當提供回呼時,會傳遞可能的錯誤和呈現的字串,而且不會執行自動回應。
res.render('index', function (err, html) {
// ...
})
res.render('user', { name: 'Tobi' }, function (err, html) {
// ...
})
res.req
此屬性包含對應於此回應物件的 要求物件 的參考。
中間件
basicAuth()
基本驗證中介軟體,將 req.user
填入使用者名稱。
簡單的使用者名稱和密碼
app.use(express.basicAuth('username', 'password'))
回呼驗證
app.use(express.basicAuth(function (user, pass) {
return user === 'tj' && pass === 'wahoo'
}))
非同步回呼驗證,接受 fn(err, user)
,在此情況下,req.user
會是傳遞的使用者物件。
app.use(express.basicAuth(function (user, pass, fn) {
User.authenticate({ user: user, pass: pass }, fn)
}))
bodyParser()
要求主體剖析中介軟體,支援 JSON、URL 編碼和多部分要求。此中介軟體只是 json()
、urlencoded()
和 multipart()
中介軟體的包裝器。
app.use(express.bodyParser())
// is equivalent to:
app.use(express.json())
app.use(express.urlencoded())
app.use(express.multipart())
基於安全性考量,如果應用程式不需要上傳檔案,最好停用檔案上傳功能。為此,請僅使用必要的中間件,亦即不要使用 bodyParser
和 multipart()
中間件
app.use(express.json())
app.use(express.urlencoded())
如果應用程式需要上傳檔案,您應該設定 處理這些檔案的策略。
compress()
使用 gzip / deflate 壓縮回應資料。此中間件應置於堆疊中「較高」的位置,以確保所有回應都能壓縮。
app.use(express.logger())
app.use(express.compress())
app.use(express.methodOverride())
app.use(express.bodyParser())
cookieParser()
剖析 Cookie 標頭欄位,並使用 cookie 名稱作為鍵值,將物件填入 req.cookies
。您也可以選擇透過傳遞 secret
字串來啟用簽署 cookie 支援功能。
app.use(express.cookieParser())
app.use(express.cookieParser('some secret'))
cookieSession()
提供基於 cookie 的工作階段,並填入 req.session
。此中間件採用下列選項
key
cookie 名稱,預設為connect.sess
secret
防止 cookie 遭竄改cookie
工作階段 cookie 設定,預設為{ path: '/', httpOnly: true, maxAge: null }
proxy
設定安全 cookie 時信任反向代理程式(透過「x-forwarded-proto」)
app.use(express.cookieSession())
若要清除 cookie,只需在回應之前將工作階段指定為 null
req.session = null
csrf()
CSRF 保護中間件。
預設情況下,此中間件會產生名為「_csrf」的 token,此 token 應加入到會變更狀態的請求中,例如隱藏的表單欄位、查詢字串等。此 token 會與 req.csrfToken()
進行驗證。
預設的 value
函式會檢查 bodyParser()
中間件產生的 req.body
、query()
產生的 req.query
,以及「X-CSRF-Token」標頭欄位。
此中間件需要工作階段支援,因此應新增在 session()
的下方。
directory()
目錄提供中間件,提供指定的 path
。此中間件可以與 static()
配對使用,以提供檔案,提供功能齊全的檔案瀏覽器。
app.use(express.directory('public'))
app.use(express.static('public'))
此中間件接受下列選項
hidden
顯示隱藏的(點)檔案。預設為 false。icons
顯示圖示。預設為 false。filter
將此篩選函式套用至檔案。預設為 false。