Node.js Express 框架學習
轉載:http://javascript.ruanyifeng.com/nodejs/express.html#toc0
感覺很牛的樣子,不過覺得對初學者沒太大用,裡面很多例子用的api都沒有詳細的說明。為了學習備份,所以拷貝過來。
Express框架
來自《JavaScript 標準參考教程(alpha)》,by 阮一峰
目錄
- 概述
- 執行原理
- 底層:http模組
- 對http模組的再包裝
- 什麼是中介軟體
- use方法
- Express的方法
- all方法和HTTP動詞方法
- set方法
- response物件
- requst物件
- 專案開發例項
- 編寫啟動指令碼
- 配置路由
- 靜態網頁模板
- 動態網頁模板
- 安裝模板引擎
- 新建資料指令碼
- 新建網頁模板
- 渲染模板
- 指定靜態檔案目錄
- ExpressJS 4.0的Router用法
- 基本用法
- router.route方法
- router中介軟體
- 對路徑引數的處理
- app.route
- 參考連結
概述
Express是目前最流行的基於Node.js的Web開發框架,提供各種模組,可以快速地搭建一個具有完整功能的網站。
Express的上手非常簡單,首先新建一個專案目錄,假定叫做hello-world。
$ mkdir hello-world
進入該目錄,新建一個package.json檔案,內容如下。
{
"name": "hello-world",
"description": "hello world test app",
"version": "0.0.1",
"private": true,
"dependencies": {
"express": "4.x"
}
}
上面程式碼定義了專案的名稱、描述、版本等,並且指定需要4.0版本以上的Express。
然後,就可以安裝了。
$ npm install
安裝了Express及其依賴的模組以後,在專案根目錄下,新建一個啟動檔案,假定叫做index.js。
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.listen(8080);
上面程式碼執行之後,訪問http://localhost:8080
,就會在瀏覽器中開啟當前目錄的public子目錄。如果public目錄之中有一個圖片檔案my_image.png,那麼可以用http://localhost:8080/my_image.png
訪問該檔案。
你也可以在index.js之中,生成動態網頁。
// index.js
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello world!');
});
app.listen(3000);
然後,在命令列下執行下面的命令,就可以在瀏覽器中訪問專案網站了。
node index
預設情況下,網站執行在本機的3000埠,網頁顯示Hello World。
index.js中的app.get
用於指定不同的訪問路徑所對應的回撥函式,這叫做“路由”(routing)。上面程式碼只指定了根目錄的回撥函式,因此只有一個路由記錄,實際應用中,可能有多個路由記錄。這時,最好就把路由放到一個單獨的檔案中,比如新建一個routes子目錄。
// routes/index.js
module.exports = function (app) {
app.get('/', function (req, res) {
res.send('Hello world');
});
};
然後,原來的index.js就變成下面這樣。
// index.js
var express = require('express');
var app = express();
var routes = require('./routes')(app);
app.listen(3000);
執行原理
底層:http模組
Express框架建立在node.js內建的http模組上。 http模組生成伺服器的原始程式碼如下。
var http = require("http");
var app = http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Hello world!");
});
app.listen(3000, "localhost");
上面程式碼的關鍵是http模組的createServer方法,表示生成一個HTTP伺服器例項。該方法接受一個回撥函式,該回調函式的引數,分別為代表HTTP請求和HTTP迴應的request物件和response物件。
對http模組的再包裝
Express框架的核心是對http模組的再包裝。上面的程式碼用Express改寫如下。
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello world!');
});
app.listen(3000);
var express = require("express");
var http = require("http");
var app = express();
app.use(function(request, response) {
response.writeHead(200, { "Content-Type": "text/plain" });
response.end("Hello world!\n");
});
http.createServer(app).listen(1337);
比較兩段程式碼,可以看到它們非常接近,唯一的差別是createServer方法的引數,從一個回撥函式變成了一個Epress物件的例項。而這個例項使用了use方法,載入了與上一段程式碼相同的回撥函式。
Express框架等於在http模組之上,加了一箇中間層,而use方法則相當於呼叫中介軟體。
什麼是中介軟體
簡單說,中介軟體(middleware)就是處理HTTP請求的函式,用來完成各種特定的任務,比如檢查使用者是否登入、分析資料、以及其他在需要最終將資料傳送給使用者之前完成的任務。它最大的特點就是,一箇中間件處理完,再傳遞給下一個中介軟體。
node.js的內建模組http的createServer方法,可以生成一個伺服器例項,該例項允許在執行過程中,呼叫一系列函式(也就是中介軟體)。當一個HTTP請求進入伺服器,伺服器例項會呼叫第一個中介軟體,完成後根據設定,決定是否再呼叫下一個中介軟體。中介軟體內部可以使用伺服器例項的response物件(ServerResponse,即回撥函式的第二個引數),以及一個next回撥函式(即第三個引數)。每個中介軟體都可以對HTTP請求(request物件)做出迴應,並且決定是否呼叫next方法,將request物件再傳給下一個中介軟體。
一個不進行任何操作、只傳遞request物件的中介軟體,大概是下面這樣:
function uselessMiddleware(req, res, next) {
next();
}
上面程式碼的next為中介軟體的回撥函式。如果它帶有引數,則代表丟擲一個錯誤,引數為錯誤文字。
function uselessMiddleware(req, res, next) {
next('出錯了!');
}
丟擲錯誤以後,後面的中介軟體將不再執行,直到發現一個錯誤處理函式為止。
use方法
use是express呼叫中介軟體的方法,它返回一個函式。下面是一個連續呼叫兩個中介軟體的例子。
var express = require("express");
var http = require("http");
var app = express();
app.use(function(request, response, next) {
console.log("In comes a " + request.method + " to " + request.url);
next();
});
app.use(function(request, response) {
response.writeHead(200, { "Content-Type": "text/plain" });
response.end("Hello world!\n");
});
http.createServer(app).listen(1337);
上面程式碼先呼叫第一個中介軟體,在控制檯輸出一行資訊,然後通過next方法,呼叫第二個中介軟體,輸出HTTP迴應。由於第二個中介軟體沒有呼叫next方法,所以不再request物件就不再向後傳遞了。
使用use方法,可以根據請求的網址,返回不同的網頁內容。
var express = require("express");
var http = require("http");
var app = express();
app.use(function(request, response, next) {
if (request.url == "/") {
response.writeHead(200, { "Content-Type": "text/plain" });
response.end("Welcome to the homepage!\n");
} else {
next();
}
});
app.use(function(request, response, next) {
if (request.url == "/about") {
response.writeHead(200, { "Content-Type": "text/plain" });
} else {
next();
}
});
app.use(function(request, response) {
response.writeHead(404, { "Content-Type": "text/plain" });
response.end("404 error!\n");
});
http.createServer(app).listen(1337);
上面程式碼通過request.url屬性,判斷請求的網址,從而返回不同的內容。
除了在回撥函式內部,判斷請求的網址,Express也允許將請求的網址寫在use方法的第一個引數。
app.use('/', someMiddleware);
上面程式碼表示,只對根目錄的請求,呼叫某個中介軟體。
因此,上面的程式碼可以寫成下面的樣子。
var express = require("express");
var http = require("http");
var app = express();
app.use("/", function