您現在的位置是:首頁 > 娛樂

Express 4.x API 中文參考手冊

由 文江部落格 發表于 娛樂2022-02-10
簡介sendStatus(statusCode)設定響應物件的HTTP status code為statusCode並且傳送statusCode的相應的字串形式作為響應的Body

expires是什麼意思

express()

express()

用來建立一個Express的程式。

express()

方法是

express

模組匯出的頂層方法。

var express = require(‘express’);var app = express();

Methods

express。static(root, [options])

express。static

是Express中唯一的內建中介軟體。它以 server-static 模組為基礎開發,負責託管 Express 應用內的靜態資源。

引數

root

為靜態資源的所在的根目錄。

引數

options

是可選的,支援以下的屬性:

Express 4.x API 中文參考手冊

如果你想獲得更多關於使用中介軟體的細節,你可以查閱 Serving static files in Express 。

Application()

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 。

它還有一些屬性設定,這些屬性可以改變程式的行為。獲得更多的資訊,可以查閱 Application settings 。

Properties

app。locals

app。locals

物件是一個javascript物件,它的屬性就是程式本地的變數。

app。locals。title// => ‘My App’app。locals。email// => ‘me@myapp。com’

一旦設定,

app。locals

的各屬性值將貫穿程式的整個生命週期,與其相反的是

res。locals

,它只在這次請求的生命週期中有效。

在程式中,你可以在渲染模板時使用這些本地變數。它們是非常有用的,可以為模板提供一些有用的方法,以及

app

級別的資料。透過

req。app。locals

(具體檢視 req。app ),Locals可以在中介軟體中使用。

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 appvar admin = express(); // the sub appadmin。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。log(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 appapp。use([‘/adm*n’, ‘/manager’], admin); // load the ‘admin’ router on ‘/adm*n’ and ‘/manager’ , on the parent app

Events

app。on(‘mount’, callback(parent))

當子程式被掛載到父程式時,

mount

事件被髮射。父程式物件作為引數,傳遞給回撥方法。

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);

Methods

app。all(path, callback[, callback 。。。]

app。all

方法和標準的

app。METHOD()

方法相似,除了它匹配所有的HTTP動詞。

對於給一個特殊字首對映一個全域性的邏輯處理,或者無條件匹配,它是很有效的。例如,如果你把下面內容放在所有其他的路由定義的前面,它要求所有從這個點開始的路由需要認證和自動載入一個使用者。記住這些回撥並不是一定是終點:

loadUser

可以在完成了一個任務後,呼叫

next()

方法來繼續匹配隨後的路由。

app。all(‘*’, requireAuthentication, loadUser);

或者這種相等的形式:

app。all(‘*’, requireAuthentication); app。all(‘*’, loadUser);

另一個例子是全域性的白名單方法。這個例子和前面的很像,然而它只是限制以

/api

開頭的路徑。

app。all(‘/api/*’, requireAuthentication);

app。delete(path, callback[, callback 。。。])

路由

HTTP DELETE

請求到有特殊回撥方法的特殊的路徑。獲取更多的資訊,可以查閱 routing guide 。

你可以提供多個回撥函式,它們的行為和中介軟體一樣,除了這些回撥可以透過呼叫

next(‘router’)

來繞過剩餘的路由回撥。你可以使用這個機制來為一個路由設定一些前提條件,如果不能滿足當前路由的處理條件,那麼你可以傳遞控制到隨後的路由。

app。delete(‘/’, function(req, res) { res。send(‘DELETE request to homepage’);});

app。disable(name)

設定型別為布林的設定名為

name

的值為

false

,此處的

name

是 app settings table 中各屬性的一個。呼叫

app。set(‘foo’, false)

和呼叫

app。disable(‘foo’)

是等價的。

比如:

app。disable(‘trust proxy’);app。get(‘trust proxy’);// => false

app。disabled(name)

返回

true

如果布林型別的設定值

name

被禁用為

false

,此處的

name

是 app settings table 中各屬性的一個。

app。disabled(‘trust proxy’); // => true app。enable(‘trust proxy’); app。disabled(‘trust proxy’); // => false

app。enable(name)

設定布林型別的設定值

name

true

,此處的

name

是 app settings table 中各屬性的一個。呼叫

app。set(‘foo’, true)

和呼叫

app。enable(‘foo’)

是等價的。

app。enable(‘trust proxy’); app。get(‘trust proxy’); // => true

app。enabled(name)

返回

true

如果布林型別的設定值

name

被啟動為

true

,此處的

name

是 app settings table 中各屬性的一個。

app。enabled(‘trust proxy’); // => false app。enable(‘trust proxy’); app。enabled(‘trust proxy’); // => true

app。engine(ext, callback)

註冊給定引擎的回撥,用來渲染處理ext檔案。

預設情況下,Express需要使用

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。get(name)

獲得設定名為

name

的app設定的值,此處的

name

是 app settings table 中各屬性的一個。

如下:

app。get(‘title’);// => undefinedapp。set(‘title’, ‘My Site’);app。get(‘title’);// => ‘My Site’

app。get(path, callback [, callback 。。。])

路由

HTTP GET

請求到有特殊回撥的特殊路徑。獲取更多的資訊,可以查閱 routing guide 。

你可以提供多個回撥函式,它們的行為和中介軟體一樣,除了這些回撥可以透過呼叫

next(‘router’)

來繞過剩餘的路由回撥。你可以使用這個機制來為一個路由設定一些前提條件,如果請求沒能滿足當前路由的處理條件,那麼傳遞控制到隨後的路由。

app。get(‘/’, function(req, res) { res。send(‘GET request to homepage’); });

app。listen(port, [hostname], [backlog], [callback])

繫結程式監聽埠到指定的主機和埠號。這個方法和

Node

中的 http。Server。listen() 是一樣的。

var express = require(‘express’); var app = express(); app。listen(3000);

透過呼叫

express()

返回得到的

app

實際上是一個JavaScript的

Function

,被設計用來作為一個回撥傳遞給

Node HTTP servers

來處理請求。這樣,其就可以很簡便的基於同一份程式碼提供http和https版本,所以app沒有從這些繼承(它只是一個簡單的回撥)。

var express = require(‘express’); var https = require(‘https’); var http = require(‘http’); http。createServer(app)。listen(80); https。createServer(options, app)。listen(443);

app。listen()

方法是下面所示的一個便利的方法(只針對HTTP協議):

app。listen = function() { var server = http。createServer(this); return server。listen。apply(server, arguments); };

app。METHOD(path, callback [, callback 。。。])

路由一個HTTP請求,

METHOD

是這個請求的HTTP方法,比如

GET

PUT

POST

等等,注意是小寫的。所以,實際的方法是

app。get()

app。post()

app。put()

等等。下面有關於方法的完整的表。

獲取更多資訊,請看 routing guide 。

Express支援下面的路由方法,對應與同名的HTTP方法:

Express 4.x API 中文參考手冊

如果使用上述方法時,導致了無效的javascript的變數名,可以使用中括號符號,比如,

app[‘m-search’](‘/’, function 。。。

你可以提供多個回撥函式,它們的行為和中介軟體一樣,除了這些回撥可以透過呼叫

next(‘router’)

來繞過剩餘的路由回撥。你可以使用這個機制來為一個路由設定一些前提條件,如果請求沒有滿足當前路由的處理條件,那麼傳遞控制到隨後的路由。

本API文件把使用比較多的HTTP方法

app。get()

app。post

app。put()

app。delete()

作為一個個單獨的項進行說明。然而,其他上述列出的方法以完全相同的方式工作。

app。all()

是一個特殊的路由方法,它不屬於HTTP協議中的規定的方法。它為一個路徑載入中介軟體,其對所有的請求方法都有效。

app。all(‘/secret’, function (req, res) { console。log(‘Accessing the secret section。。。’); next(); // pass control to the next handler });

app。param([name], callback)

給路由引數添加回調觸發器,這裡的

name

是引數名或者引數陣列,

function

是回撥方法。回撥方法的引數按序是

請求物件

響應物件

下箇中間件

引數值

引數名

如果

name

是陣列,會按照各個引數在陣列中被宣告的順序將回調觸發器註冊下來。還有,對於除了最後一個引數的其他引數,在他們的回撥中呼叫

next()

來呼叫下個宣告引數的回撥。對於最後一個引數,在回撥中呼叫

next()

將呼叫位於當前處理路由中的下一個中介軟體,如果

name

只是一個

string

那就和它是一樣的(就是說只有一個引數,那麼就是最後一個引數,和陣列中最後一個引數是一樣的)。

例如,當

:user

出現在路由路徑中,你可以對映使用者載入的邏輯處理來自動提供

req。user

給這個路由,或者對輸入的引數進行驗證。

app。param(‘user’, function(req, res, next, id) { User。find(id, function(error, user) { if (err) { next(err); } else if (user){ req。user = user; } else { next(new Error(‘failed to load user’)); } }); });

對於

Param

的回撥定義的路由來說,他們是區域性的。它們不會被掛載的app或者路由繼承。所以,定義在

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 mathces too’); res。end();});

GET /user/42

,得到下面的結果:

CALLED ONLY ONCEalthough this matchesand 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, next) { console。log(‘and this matches too’); res。end();});

當執行

GET /user/42/3

,結果如下:

CALLED ONLY ONCE with 42CALLED ONLY ONCE with 3although this matchesand this mathes too

下面章節描述的

app。param(callback)

在v4。11。0之後被棄用。

透過只傳遞一個回撥引數給

app。param(name, callback)

方法,

app。param(naem, callback)

方法的行為將被完全改變。這個回撥引數是關於

app。param(name, callback)

該具有怎樣的行為的一個自定義方法,這個方法必須接受兩個引數並且返回一箇中間件。

這個回撥的第一個引數就是需要捕獲的url的引數名,第二個引數可以是任一的JavaScript物件,其可能在實現返回一箇中間件時被使用。

這個回撥方法返回的中介軟體決定了當URL中包含這個引數時所採取的行為。

在下面的例子中,

app。param(name, callback)

引數簽名被修改成了

app。param(name, accessId)

。替換接受一個引數名和回撥,

app。param()

現在接受一個引數名和一個數字。

var express = require(‘express’);var app = express();app。param(function(param, option){ return function(req, res, next, val) { if (val == option) { next(); } else { res。sendStatus(403); } }});app。param(‘id’, 1337);app。get(‘/user/:id’, function(req, res) { res。send(‘Ok’);});app。listen(3000, function() { console。log(‘Ready’);});

在這個例子中,

app。param(name, callback)

引數簽名保持和原來一樣,但是替換成了一箇中間件,定義了一個自定義的資料型別檢測方法來檢測

user id

的型別正確性。

app。param(function(param, validator) { return function(req, res, next, val) { if (validator(val)) { next(); } else { res。sendStatus(403); } }});app。param(‘id’, function(candidate) { return !isNaN(parseFloat(candidate)) && isFinite(candidate);});

在使用正則表示式來,不要使用

。例如,你不能使用

/user-。+/

來捕獲

user-gami

,用使用

[\\s\\S]

或者

[\\w\\>W]

來代替(正如

/user-[\\s\\S]+/

)。

//captures ‘1-a_6’ but not ‘543-azser-sder’router。get(‘/[0-9]+-[[\\w]]*’, function); //captures ‘1-a_6’ and ‘543-az(ser“-sder’ but not ‘5-a s’router。get(‘/[0-9]+-[[\\S]]*’, function); //captures all (equivalent to ‘。*’)router。get(‘[[\\s\\S]]*’, function);

app。path()

透過這個方法可以得到

app

典型的路徑,其是一個

string

var app = express() , blog = express() , blogAdmin = express();app。use(‘/blog’, blog);app。use(‘/admin’, blogAdmin);console。log(app。path()); // ‘’console。log(blog。path()); // ‘/blog’console。log(blogAdmin。path()); // ‘/blog/admin’

如果

app

掛載很複雜下,那麼這個方法的行為也會很複雜:一種更好用的方式是使用

req。baseUrl

來獲得這個app的典型路徑。

app。post(path, callback, [callback 。。。])

路由

HTTP POST

請求到有特殊回撥的特殊路徑。獲取更多的資訊,可以查閱 routing guide 。

你可以提供多個回撥函式,它們的行為和中介軟體一樣,除了這些回撥可以透過呼叫

next(‘router’)

來繞過剩餘的路由回撥。你可以使用這個機制來為一個路由設定一些前提條件,如果請求沒能滿足當前路由的處理條件,那麼傳遞控制到隨後的路由。

app。post(‘/’, function(req, res) { res。send(‘POST request to homepage’) });

app。put(path, callback, [callback 。。。])

路由

HTTP PUT

請求到有特殊回撥的特殊路徑。獲取更多的資訊,可以查閱 routing guide 。

你可以提供多個回撥函式,它們的行為和中介軟體一樣,除了這些回撥可以透過呼叫

next(‘router’)

來繞過剩餘的路由回撥。你可以使用這個機制來為一個路由設定一些前提條件,如果請求沒能滿足當前路由的處理條件,那麼傳遞控制到隨後的路由。

app。put(‘/’, function(req, res) { res。send(‘PUT request to homepage’); });

app。render(view, [locals], callback)

透過

callback

回撥返回一個

view

渲染之後得到的HTML文字。它可以接受一個可選的引數,可選引數包含了這個

view

需要用到的本地資料。這個方法類似於

res。render()

除了它不能把渲染得到的HTML文字傳送給客戶端

app。render()

當作是可以生成渲染檢視字串的工具方法。在

res。render()

內部,就是使用的

app。render()

來渲染檢視。

如果使能了檢視快取,那麼本地變數快取就會保留。如果你想在開發的過程中快取檢視,設定它為

true

。在生產環境中,檢視快取預設是開啟的。

app。render(‘email’, function(err, html) {// 。。。});app。render(‘email’, {name:‘Tobi’}, function(err, html) {// 。。。});

app。route(path)

返回一個單例模式的路由的例項,之後你可以在其上施加各種HTTP動作的中介軟體。使用

app。route()

來避免重複路由名字(例如錯字錯誤)——說的意思應該是使用

app。router()

這個單例方法來避免同一個路徑多個路由例項。

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

值,

name

是 app settings table 中屬性的一項。

對於一個型別是布林型的屬性呼叫

app。set(‘foo’, ture)

等價於呼叫

app。enable(‘foo’)

。同樣的,呼叫

app。set(‘foo’, false)

等價於呼叫

app。disable(‘foo’)

可以使用

app。get()

來取得設定的值:

app。set(‘title’, ‘My Site’); app。get(‘title’); // ‘My Site’

Application Settings

如果

name

是程式設定之一,它將影響到程式的行為。下邊列出了程式中的設定。

Express 4.x API 中文參考手冊

Options for trust proxy settings

查閱 Express behind proxies 來獲取更多資訊。

Express 4.x API 中文參考手冊

Options for etag settings

ETag

功能的實現使用了 etag 包。如果你需要獲得更多的資訊,你可以查閱它的文件。

Express 4.x API 中文參考手冊

app。use([path,], function [, function。。。])

掛載 中介軟體 方法到路徑上。如果路徑未指定,那麼預設為”/“。

一個路由將匹配任何路徑如果這個路徑以這個路由設定路徑後緊跟著”/“。比如:

app。use(‘/appale’, 。。。)

將匹配”/apple“,”/apple/images“,”/apple/images/news“等。

中介軟體中的

req。originalUrl

req。baseUrl

req。path

的組合,如下面的例子所示。

app。use(‘/admin’, function(req, res, next) {// GET ‘http://www。example。com/admin/new’console。log(req。originalUrl); // ‘/admin/new’console。log(req。baseUrl); // ‘/admin’console。log(req。path);// ‘/new’});

在一個路徑上掛載一箇中間件之後,每當請求的路徑的字首部分匹配了這個路由路徑,那麼這個中介軟體就會被執行。

由於預設的路徑為

/

,中介軟體掛載沒有指定路徑,那麼對於每個請求,這個中介軟體都會被執行。

// this middleware will be executed for every request to the app。 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’); }); // this middleware will never reach this route app。use(‘/’, function(req, res) { res。send(‘Welcome’); });

路徑可以是代表路徑的一串字元,一個路徑模式,一個匹配路徑的正則表示式,或者他們的一組集合。

下面是路徑的簡單的例子。

Express 4.x API 中文參考手冊

方法可以是一箇中間件方法,一系列中介軟體方法,一組中介軟體方法或者他們的集合。由於

router

app

實現了中介軟體介面,你可以像使用其他任一中介軟體方法那樣使用它們。

Express 4.x API 中文參考手冊

下面是一些例子,在

Express

程式中使用

express。static

中介軟體。

為程式託管位於程式目錄下的

public

目錄下的靜態資源:

// GET /style。css etcapp。use(express。static(__dirname + ‘/public’));

/static

路徑下掛載中介軟體來提供靜態資源託管服務,只當請求是以

/static

為字首的時候。

// GET /static/style。css etc。app。use(‘/static’, express。static(express。__dirname + ‘/public’));

透過在設定靜態資源中介軟體之後載入日誌中介軟體來關閉靜態資源請求的日誌。

app。use(express。static(__dirname + ‘/public’)); app。use(logger());

託管靜態資源從不同的路徑,但

。/public

路徑比其他更容易被匹配:

app。use(express。static(__dirname + ‘/public’));app。use(express。static(__dirname + ‘/files’));app。use(express。static(__dirname + ‘/uploads’));

Request

req

物件代表了一個HTTP請求,其具有一些屬性來儲存請求中的一些資料,比如

query string

parameters

body

HTTP headers

等等。在本文件中,按照慣例,這個物件總是簡稱為

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); });

Properties

Express 4

中,

req。files

預設在

req

物件中不再是可用的。為了透過

req。files

物件來獲得上傳的檔案,你可以使用一個

multipart-handling

(多種處理的工具集)中介軟體,比如

busboy

multer

formidable

multipraty

connect-multiparty

或者

pez

req。app

這個屬性持有

express

程式例項的一個引用,其可以作為中介軟體使用。

如果你按照這個模式,你建立一個模組匯出一箇中間件,這個中介軟體只在你的主檔案中

require()

它,那麼這個中介軟體可以透過

req。app

來獲取express的例項。

例如:

// index。js app。get(”/viewdirectory“, require(‘。/mymiddleware。js’));

// mymiddleware。jsmodule。exports = function(req, res) { res。send(‘The views directory is ’ + req。app。get(‘views’));};

req。baseUrl

一個路由例項掛載的Url路徑。

var greet = express。Router(); greet。get(‘/jp’, function(req, res) { console。log(req。baseUrl); // greet res。send(‘Konichiwa!’); }); app。use(‘/greet’, greet);

即使你使用的路徑模式或者一系列路徑模式來載入路由,

baseUrl

屬性返回匹配的字串,而不是路由模式。下面的例子,

greet

路由被載入在兩個路徑模式上。

app。use([‘/gre+t’, ‘hel{2}o’], greet); // load the on router on ‘/gre+t’ and ‘/hel{2}o’

當一個請求路徑是

/greet/jp

baseUrl

/greet

,當一個請求路徑是

/hello/jp

req。baseUrl

/hello

req。baseUrl

app

物件的 mountpath 屬性相似,除了

app。mountpath

返回的是路徑匹配模式。

req。body

在請求的body中儲存的是提交的一對對鍵值資料。預設情況下,它是

undefined

,當你使用比如

body-parser

multer

這類解析

body

資料的中介軟體時,它是填充的。

下面的例子,給你展示了怎麼使用

body-parser

中介軟體來填充

req。body

var app = require(‘express’); var bodyParser = require(‘body-parser’); var multer = require(‘multer’);// v1。0。5 var upload = multer(); // for parsing multipart/form-data app。use(bodyParser。json()); // for parsing application/json app。use(bodyParser。urlencoded({extended:true})); // for parsing application/x-www-form-urlencoded app。post(‘/profile’, upload。array(), function(req, res, next) { console。log(req。body); res。json(req。body); });

req。cookies

當使用

cookie-parser

中介軟體的時候,這個屬性是一個物件,其包含了請求傳送過來的

cookies

。如果請求沒有帶

cookies

,那麼其值為

{}

// Cookie: name=tj req。cookies。name // => ”tj“

獲取更多資訊,問題,或者關注,可以查閱 cookie-parser 。

req。fresh

指示這個請求是否是新鮮的。其和

req。stale

是相反的。

cache-control

請求頭沒有

no-cache

指示和下面中的任一一個條件為

true

,那麼其就為

true

if-modified-since

請求頭被指定,和

last-modified

請求頭等於或者早於

modified

響應頭。

if-none-match

請求頭是

*

if-none-match

請求頭在被解析進它的指令之後,和

etag

響應頭的值不相等

ps:If-None-Match作用: If-None-Match和ETag一起工作,工作原理是在HTTP Response中新增ETag資訊。 當用戶再次請求該資源時,將在HTTP Request 中加入If-None-Match資訊(ETag的值)。如果伺服器驗證資源的ETag沒有改變(該資源沒有更新),將返回一個304狀態告訴客戶端使用本地快取檔案。否則將返回200狀態和新的資源和Etag。 使用這樣的機制將提高網站的效能

req。fresh // => true

req。hostname

包含了源自

Host

HTTP頭部的

hostname

trust proxy

設定項被設定為啟用值,

X-Forwarded-Host

頭部被使用來代替

Host

。這個頭部可以被客戶端或者代理設定。

// Host: ”example。com“req。hostname// => ”example。com“

req。ips

trust proxy

設定項被設定為啟用值,這個屬性包含了一組在

X-Forwarded-For

請求頭中指定的IP地址。不然,其就包含一個空的陣列。這個頭部可以被客戶端或者代理設定。

例如,如果

X-Forwarded-For

client

proxy1

proxy2

req。ips

就是

[”clinet“, ”proxy1“, ”proxy2“]

,這裡

proxy2

就是最遠的下游。

req。originalUrl

req。url

不是一個原生的

Express

屬性,它繼承自 Node‘s http module 。

這個屬性很像

req。url

;然而,其保留了原版的請求連結,允許你自由地重定向

req。url

到內部路由。比如,

app。use()

mounting

特點可以重定向

req。url

跳轉到掛載點。

// GET /search?q=somethingreq。originalUrl// => ”/search?q=something“

req。params

一個物件,其包含了一系列的屬性,這些屬性和在路由中命名的引數名是一一對應的。例如,如果你有

/user/:name

路由,

name

屬性可作為

req。params。name

。這個物件預設值為

{}

// GET /user/tjreq。params。name// => ”tj“

當你使用正則表示式來定義路由規則,捕獲組的組合一般使用

req。params[n]

,這裡的

n

是第幾個捕獲租。這個規則被施加在無名萬用字元匹配,比如

/file/*

的路由:

// GET /file/javascripts/jquery。jsreq。params[0]// => ”javascripts/jquery。js“

req。path

包含請求URL的部分路徑。

// example。com/users?sort=descreq。path// => ”/users“

當在一箇中間件中被呼叫,掛載點不包含在

req。path

中。你可以查閱 app。use() 獲得跟多的資訊。

req。protocol

請求的協議,一般為

http

,當啟用TLS加密,則為

https

trust proxy

設定一個啟用的引數,如果存在

X-Forwarded-Proto

頭部的話,其將被信賴和使用。這個頭部可以被客戶端或者代理設定。

req。ptotocol// => ”http“

req。query

一個物件,為每一個路由中的

query string

引數都分配一個屬性。如果沒有

query string

,它就是一個空物件,

{}

// GET /search?q=tobi+ferretreq。query。q// => ”tobi ferret“// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=conversereq。query。order// => ”desc“req。query。shoe。color// => ”blue“req。query。shoe。type// => ”converse“

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

。等價與:

’https‘ == req。protocol;

req。signedCookies

當使用

cookie-parser

中介軟體的時候,這個屬性包含的是請求發過來的簽名

cookies

,這個屬性取得的是不含簽名,可以直接使用的值。簽名的

cookies

儲存在不同的物件中來體現開發者的意圖;不然,一個惡意攻擊可以被施加在

req。cookie

值上(它是很容易被欺騙的)。記住,簽名一個

cookie

不是把它藏起來或者加密;而是簡單的防止篡改(因為簽名使用的加密是私人的)。如果沒有傳送簽名的

cookie

,那麼這個屬性預設為

{}

// Cookie: user=tobi。CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3req。signedCookies。user// => ”tobi“

為了獲取更多的資訊,問題或者關注,可以參閱 cookie-parser 。

req。stale

指示這個請求是否是

stale

(陳舊的),它與

req。fresh

是相反的。更多資訊,可以檢視 req。fresh 。

req。stale// => true

req。subdomains

請求中域名的子域名陣列。

// Host: ”tobi。ferrets。example。com“req。subdomains// => [”ferrets“, ”tobi“]

req。xhr

一個布林值,如果

X-Requested-With

的值為

XMLHttpRequest

,那麼其為

true

,其指示這個請求是被一個客服端庫傳送,比如

jQuery

req。xhr// => true

Methods

req。accepts(types)

檢查這個指定的內容型別是否被接受,基於請求的

Accept

HTTP頭部。這個方法返回最佳匹配,如果沒有一個匹配,那麼其返回

undefined

(在這個case下,伺服器端應該返回406和”Not Acceptable“)。

type

值可以是一個單的

MIME type

字串(比如

application/json

),一個副檔名比如

json

,一個逗號分隔的列表,或者一個數組。對於一個列表或者陣列,這個方法返回最佳項(如果有的話)。

// Accept: text/htmlreq。accepts(’html‘);// => ”html“// Accept: text/*, application/jsonreq。accepts(’html‘);// => ”html“req。accepts(’text/html‘);// => ”text/html“req。accepts([’json‘, ’text‘]);// => ”json“req。accepts(’application/json‘);// => ”application/json“// Accept: text/*, application/jsonreq。accepts(’image/png‘);req。accepts(’png‘);// => undefined// Accept: text/*;q=。5, application/jsonreq。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。

獲取更多資訊,或者如果你有問題或關注,可以參閱 accepts 。

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

頭部域匹配引數

type

給定的

MIME type

,那麼其返回

true

。否則返回

false

// With Content-Type: text/html; charset=utf-8req。is(’html‘);req。is(’text/html‘);req。is(’text/*‘);// => true// When Content-Type is application/jsonreq。is(’json‘);req。is(’application/json‘);req。is(’application/*‘);// => truereq。is(’html‘);// => false

獲取更多資訊,或者如果你有問題或關注,可以參閱 type-is 。

req。param(naem, [, defaultValue])

過時的。可以在適合的情況下,使用

req。params

req。body

或者

req。query

返回當前引數

name

的值。

// ?name=tobireq。param(’name‘)// => ”tobi“// POST name=tobireq。param(’name‘)// => ”tobi“// /user/tobi for /user/:namereq。param(’name‘)// => ”tobi“

按下面給出的順序查詢:

req。params

req。body

req。query

可選的,你可以指定一個

defaultValue

來設定一個預設值,如果這個引數在任何一個請求的物件中都不能找到。

直接透過

req。params

req。body

req。query

取得應該更加的清晰-除非你確定每一個物件的輸入。

Body-parser

中介軟體必須載入,如果你使用

req。param()

。詳細請看 req。body 。

Response

res

物件代表了當一個HTTP請求到來時,

Express

程式返回的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);});

Properties

res。app

這個屬性持有

express

程式例項的一個引用,其可以在中介軟體中使用。

res。app

和請求物件中的

req。app

屬性是相同的。

res。headersSent

布林型別的屬性,指示這個響應是否已經發送HTTP頭部。

app。get(’/‘, function(req, res) { console。log(res。headersSent); // false res。send(’OK‘); // send之後就傳送了頭部 console。log(res。headersSent); // true});

res。locals

一個物件,其包含了本次請求的響應中的變數和因此它的變數只提供給本次請求響應的週期內檢視渲染裡使用(如果有檢視的話)。

其他方面,其和

app。locals

是一樣的。

這個引數在匯出請求級別的資訊是很有效的,這些資訊比如請求路徑,已認證的使用者,使用者設定等等。

app。use(function(req, res, next) { res。locals。user = req。user; res。locals。authenticated = !req。user。anonymous; next();});

Methods

res。append(field [, value])

res。append()方法在

Expresxs

4。11。0以上版本才支援。

在指定的

field

的HTTP頭部追加特殊的值

value

。如果這個頭部沒有被設定,那麼將用

value

新建這個頭部。

value

可以是一個字串或者陣列。

注意:在

res。append()

之後呼叫

app。set()

函式將重置前面設定的值。

res。append(’Lind‘, [’‘, ’‘]);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=“parameter。

res。attachment();// Content-Disposition: attachmentres。attachment(’path/to/logo。png‘);// Content-Disposition: attachment; filename=”logo。png“// Content-Type: image/png

res。cookie(name, value [,options])

設定

name

value

cookie

value

引數可以是一串字元或者是轉化為json字串的物件。

options是一個物件,其可以有下列的屬性。

Express 4.x API 中文參考手冊

res。cookie()所作的都是基於提供的

options

引數來設定

Set-Cookie

頭部。沒有指定任何的

options

,那麼預設值在

RFC6265

中指定。

使用例項:

res。cookie(’name‘, ’tobi‘, {’domain‘:’。example。com‘, ’path‘:’/admin‘, ’secure‘:true});res。cookie(’remenberme‘, ’1‘, {’expires‘:new Date(Date。now() + 90000), ’httpOnly‘:true});

maxAge

是一個方便設定過期時間的方便的選項,其以當前時間開始的毫秒數來計算。下面的示例和上面的第二條功效一樣。

res。cookie(’rememberme‘, ’1‘, {’maxAge‘:90000}, ”httpOnly“:true);

你可以設定傳遞一個物件作為

value

的引數。然後其將被序列化為Json字串,被

bodyParser()

中介軟體解析。

res。cookie(’cart‘, {’items‘:[1, 2, 3]});res。cookie(’cart‘, {’items‘:[1, 2, 3]}, {’maxAge‘:90000});

當我們使用

cookie-parser

中介軟體的時候,這個方法也支援簽名的cookie。簡單地,在設定

options

時包含

signed

選項為

true

。然後

res。cookie()

將使用傳遞給

cookieParser(secret)

的金鑰來簽名這個值。

res。cookie(’name‘, ’tobi‘, {’signed‘:true});

res。clearCookie(name [,options])

根據指定的

name

清除對應的cookie。更多關於

options

物件可以查閱

res。cookie()

res。cookie(’name‘, ’tobi‘, {’path‘:’/admin‘});res。clearCookie(’name‘, {’path‘:’admin‘});

res。download(path, [,filename], [,fn])

傳輸

path

指定檔案作為一個附件。通常,瀏覽器提示使用者下載。預設情況下,

Content-Disposition

頭部”filename=“的引數為

path

(通常會出現在瀏覽器的對話方塊中)。透過指定

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) {// Handle error, but keep in mind the response may be partially-sent// so check res。headersSentif (err) {} else {// decrement a download credit, etc。}});

res。end([data] [, encoding])

結束本響應的過程。這個方法實際上來自

Node

核心模組,具體的是 response。end() method of http。ServerResponse 。

用來快速結束請求,沒有任何的資料。如果你需要傳送資料,可以使用 res。send() 和 res。json() 這類的方法。

res。end();res。status(404)。end();

res。format(object)

進行內容協商,根據請求的物件中

Accept

HTTP頭部指定的接受內容。它使用 req。accepts() 來選擇一個控制代碼來為請求服務,這些控制代碼按質量值進行排序。如果這個頭部沒有指定,那麼第一個方法預設被呼叫。當不匹配時,伺服器將返回

406

”Not Acceptable“,或者呼叫

default

回撥。

Content-Type

請求頭被設定,當一個回撥方法被選擇。然而你可以改變他,在這個方法中使用這些方法,比如

res。set()

或者

res。type()

下面的例子,將回復

{”message“:”hey“}

,當請求的物件中

Accept

頭部設定成”application/json“或者”*/json“(不過如果是

*/*

,然後這個回覆就是”hey“)。

res。format({ ’text/plain‘:function() { res。send(’hey‘); }, ’text/html‘:function() { res。send(’

hey

‘); }, ’application/json‘:function() { res。send({message:’hey‘}); }, ’default‘:function() { res。status(406)。send(’Not Acceptable‘); }})

除了規範化的MIME型別之外,你也可以使用拓展名來對映這些型別來避免冗長的實現:

res。format({ text:function() { res。send(’hey‘); }, html:function() { res。send(’

hey

‘); }, json:function() { res。send({message:’hey‘}); }})

res。get(field)

返回

field

指定的HTTP響應的頭部。匹配是區分大小寫。

res。get(’Content-Type‘);// => ”text/plain“

res。json([body])

傳送一個json的響應。這個方法和將一個物件或者一個數組作為引數傳遞給

res。send()

方法的效果相同。不過,你可以使用這個方法來轉換其他的值到json,例如

null

undefined

。(雖然這些都是技術上無效的JSON)。

res。json(null);res。json({user:’tobi‘});res。status(500)。json({error:’message‘});

res。jsonp([body])

傳送一個json的響應,並且支援JSONP。這個方法和

res。json()

效果相同,除了其在選項中支援JSONP回撥。

res。jsonp(null)// => nullres。jsonp({user:’tobi‘})// => {”user“ : ”tobi“}res。status(500)。jsonp({error:’message‘}) // => {”error“ : ”message“}

預設情況下,jsonp的回撥方法簡單寫作

callback

。可以透過 jsonp callback name 設定來重寫它。

下面是一些例子使用JSONP響應,使用相同的程式碼:

// ?callback=foores。jsonp({user:’tobo‘})// => foo({”user“:”tobi“})app。set(’jsonp callback name‘, ’cb‘)// ?cb=foores。status(500)。jsonp({error:’message‘})// => foo({”error“:”message“})

res。links(links)

連線這些

links

links

是以傳入引數的屬性形式提供,連線之後的內容用來填充響應的Link HTTP頭部。

res。links({ next:’http://api。example。com/users?page=2‘, last:’http://api。example。com/user?page=5‘});

效果:

Link:;rel=”next“,;rel=”last“

res。location(path)

設定響應的

Location

HTTP頭部為指定的

path

引數。

res。location(’/foo/bar‘); res。location(’http://example。com‘); res。location(’back‘);

path

引數為

back

時,其具有特殊的意義,其指定URL為請求物件的

Referer

頭部指定的URL。如果請求中沒有指定,那麼其即為”/“。

Express傳遞指定的URL字串作為回覆給瀏覽器響應中的

Location

頭部的值,不檢測和操作,除了

back

這個引數。瀏覽器會將使用者重定向到

location

設定的url或者

Referer

的url(

back

引數的情況)

res。redirect([status,] path)

重定向來源於指定

path

的URL,以及指定的 HTTP status code

status

。如果你沒有指定

status

,status code預設為”302 Found“。

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

,那麼下面將重定向到

http://example。com/admim

res。redirect(’/admin‘);

重定向也可以相對於當前的URL。比如,來之於

http://example。com/blog/admin/

(注意結尾的

/

),下面將重定向到

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])

渲染一個檢視,然後將渲染得到的HTML文件傳送給客戶端。可選的引數為:

locals

,定義了檢視本地引數屬性的一個物件。

callback

,一個回撥方法。如果提供了這個引數,

render

方法將返回錯誤和渲染之後的模板,並且不自動傳送響應。當有錯誤發生時,可以在這個回撥內部,呼叫

next(err)

方法。

本地變數快取使能檢視快取。在開發環境中快取檢視,需要手動設定為true;檢視快取在生產環境中預設開啟。

// send the rendered view to the clientres。render(’index‘);// if a callback is specified, the render HTML string has to be sent explicitlyres。render(’index‘, function(err, html) { res。send(html);});// pass a local variable to the viewres。render(’user‘, {name:’Tobi‘}, function(err, html) { // 。。。});

res。send([body])

傳送HTTP響應。

body

引數可以是一個

Buffer

物件,一個字串,一個物件,或者一個數組。比如:

res。send(new Buffer(’whoop‘));res。send({some:’json‘});res。send(’

some html

‘);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(new Buffer(’

some html

‘));

當引數是一個字串,這個方法設定

Content-Type

響應頭為

text/html

res。send(’

some html

‘);

當引數是一個物件或者陣列,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

一定是關於檔案的絕對路徑。

下面的表提供了

options

引數的細節:

Express 4.x API 中文參考手冊

當傳輸完成或者發生了什麼錯誤,這個方法呼叫

fn

回撥方法。如果這個回撥引數指定了和一個錯誤發生,回撥方法必須明確地透過結束請求-響應迴圈或者傳遞控制到下個路由來處理響應過程。

下面是使用了所有引數的使用

res。sendFile()

的例子:

app。get(’/file/:name‘, function(req, res, next) { var options = { root:__dirname + ’/public‘, dotfile:’deny‘, headers:{ ’x-timestamp‘:Date。now(), ’x-sent‘:true } }; var fileName = req。params。name; res。sendFile(fileName, options, function(err) { if (err) { console。log(err); res。status(err。status)。end(); } else { console。log(’sent‘, fileName); } });});

res。sendFile

提供了檔案服務的細粒度支援,如下例子說明:

app。get(’/user/:uid/photos/:file‘, function(req, res) { var uid = req。params。uid , file = req。params。file; req。user。mayViewFilesFrom(uid, function(yes) { if (yes) { res。sendFile(’/upload/‘ + uid + ’/‘ + file); } else { res。status(403)。send(’Sorry! you cant see that。‘); } });})

獲取更多資訊,或者你有問題或者關注,可以查閱 send 。

res。sendStatus(statusCode)

設定響應物件的

HTTP status code

statusCode

並且傳送

statusCode

的相應的字串形式作為響應的Body。

res。sendStatus(200); // equivalent to res。status(200)。send(’OK‘); res。sendStatus(403); // equivalent to res。status(403)。send(’Forbidden‘); res。sendStatus(404); // equivalent to res。status(404)。send(’Not Found‘); res。sendStatus(500); // equivalent to res。status(500)。send(’Internal Server Error‘)

如果一個不支援的狀態被指定,這個HTTP status依然被設定為

statusCode

並且用這個code的字串作為Body。

res。sendStatus(2000); // equivalent to res。status(2000)。send(’2000‘);

More about HTTP Status Codes

res。set(field [, value])

設定響應物件的HTTP頭部

field

value

。為了一次設定多個值,那麼可以傳遞一個物件為引數。

res。set(’Content-Type‘, ’text/plain‘);res。set({ ’Content-Type‘:’text/plain‘, ’Content-Length‘:’123‘, ’ETag‘:’123456‘})

其和

res。header(field [,value])

效果一致。

res。status(code)

使用這個方法來設定響應物件的HTTP status。其是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頭部的MIME type,如果這個設定的

type

能夠被 mime。lookup 解析成正確的

Content-Type

。如果

type

中包含了

/

字元,那麼程式會直接設定

Content-Type

type

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應答頭部時增加Vary應答頭部。

ps:vary的意義在於告訴代理伺服器/快取/CDN,如何判斷請求是否一樣,vary中的組合就是伺服器/快取/CDN判斷的依據,比如Vary中有User-Agent,那麼即使相同的請求,如果使用者使用IE打開了一個頁面,再用Firefox開啟這個頁面的時候,CDN/代理會認為是不同的頁面,如果Vary中沒有User-Agent,那麼CDN/代理會認為是相同的頁面,直接給使用者返回快取的頁面,而不會再去web伺服器請求相應的頁面。通俗的說就相當於

field

作為了一個快取的key來判斷是否命中快取

res。vary(’User-Agent‘)。render(’docs‘);

Router

一個

router

物件是一個單獨的例項關於中介軟體和路由。你可以認為其是一個”mini-application“(迷你程式),其具有操作中介軟體和路由方法的能力。每個

Express

程式有一個內建的app路由。

路由自身表現為一箇中間件,所以你可以使用它作為

app。use()

方法的一個引數或者作為另一個路由的

use()

的引數。

頂層的

express

物件有一個

Router()

方法,你可以使用

Router()

來建立一個新的

router

物件。

Router([options])

如下,可以建立一個路由:

var router = express。Router([options]);

options

引數可以指定路由的行為,其有下列選擇:

Express 4.x API 中文參考手冊

你可以將

router

當作一個程式,可以在其上新增中介軟體和HTTP路由方法(例如

get

put

post

等等)。

// invoked for any requests passed to this routerrouter。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上掛載一個路由,這樣你就以將你的各個路由放到不同的檔案中或者甚至是mini的程式。

// only requests to /calendar/* will be sent to our ”router“app。use(‘/calendar’, router);

Methods

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

中的METHOD是小寫的。所以,實際的方法是

router。get()

router。put()

router。post()

等等。

你可以提供多個回撥函式,它們的行為和中介軟體一樣,除了這些回撥可以透過呼叫

next(‘router’)

來繞過剩餘的路由回撥。你可以使用這個機制來為一個路由設定一些前提條件,如果請求沒有滿足當前路由的處理條件,那麼傳遞控制到隨後的路由。

下面的片段可能說明了最簡單的路由定義。Experss轉換path字串為正則表示式,用於內部匹配傳入的請求。在匹配的時候,是不考慮

Query strings

,例如,”GET /“將匹配下面的路由,”GET /?name=tobi“也是一樣的。

router。get(‘/’, function(req, res) { res。send(‘Hello World’);});

如果你對匹配的path有特殊的限制,你可以使用正則表示式,例如,下面的可以匹配”GET /commits/71dbb9c“和”GET /commits/71bb92。。4c084f9“。

router。get(/^\/commits\/(\w+)(?:\。\。(\w+))?$/, function(req, res) { var from = req。params[0]; var to = req。params[1]; res。send(‘commit range ’ + from + ‘。。’ + to);});

router。param(name, callback)

給路由引數添加回調觸發器,這裡的

name

是引數名,

function

是回撥方法。回撥方法的引數按序是請求物件,響應物件,下箇中間件,引數值和引數名。雖然

name

在技術上是可選的,但是自Express V4。11。0之後版本不推薦使用(見下面)。

不像

app。param()

router。param()

不接受一個數組作為路由引數。

例如,當

:user

出現在路由路徑中,你可以對映使用者載入的邏輯處理來自動提供

req。user

給這個路由,或者對輸入的引數進行驗證。

router。param(‘user’, function(req, res, next, id) { User。find(id, function(error, user) { if (err) { next(err); } else if (user){ req。user = user; } else { next(new Error(‘failed to load user’)); } }); });

對於

Param

的回撥定義的路由來說,他們是區域性的。它們不會被掛載的app或者路由繼承。所以,定義在

router

上的

param

回撥只有是在

router

上的路由具有這個路由引數時才起作用。

在定義

param

的路由上,

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 mathces too’); res。end();});

GET /user/42

,得到下面的結果:

CALLED ONLY ONCEalthough this matchesand this matches too

`

下面章節描述的

router。param(callback)

在v4。11。0之後被棄用。

透過只傳遞一個回撥引數給

router。param(name, callback)

方法,

router。param(naem, callback)

方法的行為將被完全改變。這個回撥引數是關於

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(); router。param(function(param, option){ return function(req, res, next, val) { if (val == option) { next(); } else { res。sendStatus(403); } } }); router。param(‘id’, 1337); router。get(‘/user/:id’, function(req, res) { res。send(‘Ok’); }); app。use(router); app。listen(3000, function() { console。log(‘Ready’); });

在這個例子中,

router。param(name。 callback)

引數簽名保持和原來一樣,但是替換成了一箇中間件,定義了一個自定義的資料型別檢測方法來檢測

user 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。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’)); })

這種方法重複使用單個

/usrs/:user_id

路徑來添加了各種的HTTP方法。

router。use([path], [function, 。。。] function)

給可選的

path

引數指定的路徑掛載給定的中介軟體方法,未指定

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 middlewarerouter。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 form the mount ponitrouter。use(‘/bar’, function(req, res, next) { // 。。。 maybe some additional /bar logging 。。。 next();})// always be invokedrouter。use(function(req, res, next) { res。send(‘hello world’);})app。use(‘/foo’, router);app。listen(3000);

對於中介軟體

function

,掛載的路徑是被剝離的和不可見的。關於這個特性主要的影響是對於不同的路徑,掛載相同的中介軟體可能對程式碼不做改動,儘管其字首已經改變。

你使用

router。use()

定義中介軟體的順序很重要。中間們是按序被呼叫的,所以順序決定了中介軟體的優先順序。例如,通常日誌是你將使用的第一個中介軟體,以便每一個請求都被記錄。

var logger = require(‘morgan’);router。use(logger());router。use(express。static(__dirname + ‘/public’));router。use(function(req, res) { res。send(‘Hello’);});

現在為了支援你不希望記錄靜態檔案請求,但為了繼續記錄那些定義在

logger()

之後的路由和中介軟體。你可以簡單的將

static()

移動到前面來解決:

router。use(express。static(__dirname + ‘/public’));router。use(logger());router。use(function(req, res){ res。send(‘Hello’);});

另外一個確鑿的例子是從不同的路徑託管靜態檔案,你可以將

。/public

放到前面來獲得更高的優先順序:

app。use(express。static(__dirname + ‘/public’));app。use(express。static(__dirname + ‘/files’));app。use(express。static(__dirname + ‘/uploads’));

router。use()

方法也支援命名引數,以便你的掛載點對於其他的路由而言,可以使用命名引數來進行預載入,這樣做是很有益的。

推薦文章

  • 即墨區大信街道開展“藝”起創城文化進萬家書法主題活動

    記者 宋祖鋒 通訊員 譚夢真為進一步推進全國文明典範城市建立工作,加大創城宣傳力度,豐富老年人文化生活,8月11日,即墨區大信街道老體協的7名書法志願者,結合全國文明典範城市建立,開展“藝”起創城文化進萬家書法主題活動...

  • 天命杯S10D6:Pero、Tyloo無緣決賽 Zpyan、Xbei同砍14殺登戰神榜

    天命杯S10D6:Pero、Tyloo無緣決賽 Zpyan、Xbei同砍14殺登戰神榜Pero就更可惜了,事實上本日Pero的圈運還算不錯的,吃到過幾次關鍵圈型,但在運營端的思路讓人捉摸不透,尤其是第四局Pero有著非常好的競爭吃雞的機會,佔據圈中心的S城城頭,但早期被城內獨狼偷掉一人導致只有三人作戰,後續圈型將S城刷走,P...

  • 龍湖智創生活:蓄力靜候時機

    龍湖智創生活:蓄力靜候時機高質量規模增長在“物管”和“商管”之間端平了水,龍湖智創生活業務涵蓋住宅及其他非商業物業管理服務,和商業運營管理服務...