性能
Express不是對
node.js 已有的特性進行二次抽象,我們只是在它之上擴展了
Web套用所需的功能。
編程接口
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');// => undefinedapp.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');// => falseapp.enable('trust proxy');
app.enabled('trust proxy');// => true
app.disabled(name)
檢查設定項 name 是否已禁用
app.disabled('trust proxy');// => trueapp.enable('trust proxy');
app.disabled('trust proxy');// => false
app.configure([env], callback)
當 env 和 app.get('env')(也就是 process.env.NODE_ENV) 匹配時, 調用
callback。保留這個方法是出於歷史原因,後面列出的
if語句的代碼其實更加高效、直接。使用app.set()配合其它一些配置方法後,沒有必要再使用這個方法。
// 所有環境app.configure(function(){
app.set('title', 'My Application');
})// 開發環境app.configure('development', function(){
app.set('db uri', 'localhost/dev');
})// 只用於生產環境app.configure('production', function(){
app.set('db uri', 'n.n.n.n/prod');
})
更高效且直接的代碼如下:
// 所有環境
app.set('title', 'My Application');
// 只用於開發環境
if ('development' == app.get('env')) {
app.set('db uri', '
localhost/dev');
}
// 只用於生產環境
if ('production' == app.get('env')) {
app.set('db uri', 'n.n.n.n/prod');
}
app.use([path], function)
使用中間件 function,可選參數path默認為"/"。
var express = require('express');var app = express();
// 一個簡單的
loggerapp.use(function(req, res, next){
console.log('%s %s', req.method, req.url);
next();
});
// 回響
app.use(function(req, res, next){
res.send('Hello World');
});
app.listen(3000);
掛載的路徑不會在req里出現,對中間件 function
不可見,這意味著你在function的
回調參數req里找不到path。這么設計的為了讓間件可以在不需要更改代碼就在任意"前綴"路徑下執行
這裡有一個實際套用場景,常見的一個套用是使用./
public提供靜態檔案服務,用 express.static() 中間件:
// GET /javascripts/jquery.js
// GET /style.css
// GET /favicon.ico
app.use(express.static(__dirname + '/public'));
如果你想把所有的靜態檔案路徑都前綴"/
static", 你可以使用“掛載”功能。如果req.url 不包含這個前綴, 掛載過的中間件
不會執行。當function被執行的時候,這個參數不會被傳遞。這個只會影響這個函式,後面的中間件里得到的 req.url里將會包含"/static"
// GET /static/javascripts/jquery.js
// GET /static/style.css
// GET /static/favicon.ico
app.use('/
static', express.static(__dirname + '/
public'));
使用 app.use() “定義的”中間件的順序非常重要,它們將會
順序執行,use的先後順序決定了中間件的
優先權。比如說通常 express.logger() 是最先使用的一個組件,紀錄每一個請求
app.use(express.logger());
app.use(express.static(__dirname + '/public'));
app.use(function(req, res){
res.send('Hello');
});
如果你想忽略請求靜態檔案的紀錄,但是對於在 logger()之後定義的路由和中間件想繼續紀錄,只需要簡單的把
static() 移到前面就行了:
app.use(express.static(__dirname + '/
public'));
app.use(express.logger());
app.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'));
settings
下面的內建的可以改變Express行為的設定
env 運行時環境,默認為 process.env.NODE_ENV 或者 "development"
trust proxy 激活
反向代理,默認未激活狀態
json replacer JSON replacer 替換時的回調, 默認為null
json spaces JSON 回響的空格數量,開發環境下是2 , 生產環境是0
case sensitive routing 路由的大小寫敏感, 默認是關閉狀態, "/Foo" 和"/foo" 是一樣的
strict routing 路由的嚴格格式, 默認情況下 "/foo" 和 "/foo/" 是被同樣對待的
view cache 模板快取,在生產環境中是默認開啟的
view engine 模板引擎
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 專門把所有的node流行的模板引擎進行了包裝,這樣它們在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定義了下面的
回調,這個允許你使用一個給定的正則去限制參數。
下面的這個例子有一點點高級,檢查如果第二個參數是一個正則,返回一個很像上面的"user"參數例子行為的
回調函式。
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.listen()
在給定的主機和連線埠上監聽請求,這個和node的文檔http.Server#listen()是一致的
var express = require('express');var app = express();
app.listen(3000);
express()返回的app實際上是一個JavaScriptFunction,它被設計為傳給node的http servers作為處理請求的
回調函式。因為app不是從HTTP或者HTTPS繼承來的,它只是一個簡單的回調函式,你可以以同一份代碼同時處理HTTP and 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,或者同時提供HTTP和HTTPS,可以使用上面的代碼
app.listen = function(){
var server = http.createServer(this);
return server.listen.apply(server, arguments);
};
版本
Express當前版本:v.4.12.3