express是在node.js的基礎上,拓展出的一個簡潔實用的框架結構,運用這個東西,咱們能夠更方便的處理不少的事情。只要上手了,那就是個貝多芬!javascript
通常安裝express有幾種方法。css
第一,使用npm安裝,cmd中輸入npm install express -g,這個-g是全局安裝,也就是安裝在被你用"config set global"設置的文件夾裏,須要注意的是,安裝完了之後,須要改變環境變量以及其路徑來指向你的安裝目錄。html
第二,複製粘貼。(……廢話!)不過這樣的存在安全性問題,由於在複製粘貼的過程當中,可能會有數據丟失之類的狀況出現。java
最後,值得注意的是,一旦在你的nodejs中存在了一個文件夾裏面放置了express框架,並且他被你引用過,那麼不管你怎麼挽救也是無用的……要麼把它刪除,要麼把它覆蓋。
node
express()jquery
建立一個express應用程序express
至關於new一個對象,可是還能少寫三個字母,將express存入變量app中,今後app翻身作主人!
npm
1
2
3
4
5
6
7
|
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安全
這個方法主要運用於設置端口,或者設置文件夾存放,其餘用途彷佛比較少見
1
2
|
app.set(
'title'
,
'My Site'
);
app.get(
'title'
);
// => "My Site"
|
app.get(name)
獲取設置項 name 的值
1
2
|
app.get(
'title'
);
// => undefinedapp.set('title', 'My Site');
app.get(
'title'
);
// => "My Site"
|
app.enable(name)
將設置項 name 的值設爲 true.
1
2
|
app.enable(
'trust proxy'
);
app.get(
'trust proxy'
);
// => true
|
app.disable(name)
將設置項 name 的值設爲 false.
1
2
|
app.disable(
'trust proxy'
);
app.get(
'trust proxy'
);
// => false
|
app.enabled(name)
檢查設置項 name 是否已啓用
1
2
|
app.enabled(
'trust proxy'
);
// => falseapp.enable('trust proxy');
app.enabled(
'trust proxy'
);
// => true
|
app.disabled(name)
檢查設置項 name 是否已禁用
1
2
|
app.disabled(
'trust proxy'
);
// => trueapp.enable('trust proxy')
app.disabled(
'trust proxy'
);
// => false
|
app.use([path], function)
這裏有一個實際應用場景,常見的一個應用是使用./public提供靜態文件服務,用 express.static() 中間件:
這裏path是使用了默認的"/",express.static()保存了資源存放的文件名,__dirname是規定的全局變量,表示開發期間,該行代碼所在的目錄(其實就是至關於當前文件夾)
1
2
3
4
|
// GET /javascripts/jquery.js
// GET /style.css
// GET /favicon.ico
app.use(express.
static
(__dirname +
'/public'
));
|
若是你想把全部的靜態文件路徑都前綴"/static", 你可使用「掛載」功能。若是req.url 不包含這個前綴, 掛載過的中間件不會執行。當function被執行的時候,這個參數不會被傳遞。這個只會影響這個函數,後面的中間件裏獲得的 req.url裏將會包含"/static"
1
2
3
4
|
// 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() 是最早使用的一個組件,紀錄每個請求
1
2
3
4
5
|
app.use(express.logger());
app.use(express.
static
(__dirname +
'/public'
));
app.use(
function
(req, res){
res.send(
'Hello'
);
});
|
若是你想忽略請求靜態文件的紀錄,可是對於在 logger()以後定義的路由和中間件想繼續紀錄,只須要簡單的把static() 移到前面就好了:
1
2
3
4
5
|
app.use(express.
static
(__dirname +
'/public'
));
app.use(express.logger());
app.use(
function
(req, res){
res.send(
'Hello'
);
});
|
另外一個現實的例子,有可能從多個目錄提供靜態文件服務,下面的例子中會優先從"./public"目錄取文件
1
2
3
|
app.use(express.
static
(__dirname +
'/public'
));
app.use(express.
static
(__dirname +
'/files'
));
app.use(express.
static
(__dirname +
'/uploads'
));
|
app.engine(ext, callback)
註冊模板引擎的 callback 用來處理ext擴展名的文件默認狀況下, 根據文件擴展名require() 對應的模板引擎。好比你想渲染一個 "foo.jade" 文件,Express會在內部執行下面的代碼,而後會緩存require(),這樣就能夠提升後面操做的性能
1
|
app.engine(
'jade'
, require(
'jade'
).__express);
|
那些沒有提供 .__express 的或者你想渲染一個文件的擴展名與模板引擎默認的不一致的時候,也能夠用這個方法。好比你想用EJS模板引擎來處理 ".html" 後綴的文件:
1
|
app.engine(
'html'
, require(
'ejs'
).renderFile);
|
這個例子中EJS提供了一個.renderFile() 方法和Express預期的格式: (path, options, callback)一致, 能夠在內部給這個方法取一個別名ejs.__express,這樣你就可使用".ejs" 擴展而不須要作任何改動
有些模板引擎沒有遵循這種轉換, 這裏有一個小項目consolidate.js 專門把全部的node流行的模板引擎進行了包裝,這樣它們在Express內部看起來就同樣了。
1
2
3
|
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).
1
2
3
4
5
6
7
8
9
10
11
12
|
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"參數例子行爲的回調函數。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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()是一致的
1
2
|
var
express = require(
'express'
);
var
app = express();
app.listen(3000);
|
express()返回的app其實是一個JavaScriptFunction,它被設計爲傳給node的http servers做爲處理請求的回調函數。由於app不是從HTTP或者HTTPS繼承來的,它只是一個簡單的回調函數,你能夠以同一份代碼同時處理HTTP and HTTPS 版本的服務。
1
2
3
4
5
|
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,可使用上面的代碼
1
2
3
4
|
app.listen =
function
(){
var
server = http.createServer(
this
);
return
server.listen.apply(server, arguments);
};
|