安裝 express
在目標文件夾下執行如下命令:
安裝完后,在目標文件夾下新建index.js文件:
然后在Node.js的命令行環境下執行“node index.js”命令,網站就運行起來了。瀏覽器訪問一下,可以輸出相應的信息。
使用
Express中的路由與路由器
Express中的路由器分為兩種類型:
app類型的路由器常使用如下代碼創建:
router類型的路由器常使用如下代碼創建:
app和router是形為function(request, response, next)形式的函數對象,使用app.verb(),router.verb()形式函數實現路由注冊(路由注冊本質上是一個觀察者模式)。
app.verb()和router.verb()中的verb常使用use、get、post、put、delete、route等動詞,不同動詞管轄的HTTP請求方法范圍不同,這些動詞函數的參數形式常為(pathExp, handleCallback)形式:其中pathExp表示請求路徑,可為正則表達式;handleCallback為路徑映射處理函數。
app是Express框架所構建程序的請求處理入口,app可作為頂層路由器使用,在應用中也可掛載下級路由器(使用router對象)以實現分級路由。
中間件
Express 是一個自身功能極簡,完全是由路由和中間件構成一個的 web 開發框架:從本質上來說,一個 Express 應用就是在調用各種中間件。
中間件(Middleware) 就是處理HTTP請求的函數,它最大的特點就是,一個中間件處理完,再傳遞給下一個中間件。App實例在運行過程中,會調用一系列的中間件。
每個中間件可以從App實例,接收三個參數,依次為request對象(代表HTTP請求)、response對象(代表HTTP回應),next回調函數(代表下一個中間件)。每個中間件都可以對HTTP請求(request對象)進行加工,並且決定是否調用next方法,將request對象再傳給下一個中間件。
use方法
use是express注冊中間件的方法,它返回一個函數。下面是一個連續調用兩個中間件的例子。
上面代碼使用app.use方法,注冊了兩個中間件。收到HTTP請求后,先調用第一個中間件,在控制台輸出一行信息,然后通過next方法,將執行權傳給第二個中間件,輸出HTTP回應。由於第二個中間件沒有調用next方法,所以request對象就不再向后傳遞了。
use方法內部可以對訪問路徑進行判斷,據此就能實現簡單的路由,根據不同的請求網址,返回不同的網頁內容。
上面代碼通過request.url屬性,判斷請求的網址,從而返回不同的內容。注意,app.use方法一共登記了三個中間件,只要請求路徑匹配,就不會將執行權交給下一個中間件。因此,最后一個中間件會返回404錯誤,即前面的中間件都沒匹配請求路徑,找不到所要請求的資源。
除了在回調函數內部判斷請求的網址,use方法也允許將請求網址寫在第一個參數。這代表,只有請求路徑匹配這個參數,后面的中間件才會生效。無疑,這樣寫更加清晰和方便。
上面代碼表示,只對根目錄的請求,調用某個中間件。
因此,上面的代碼可以寫成下面的樣子。
當你不寫路徑的時候,實際上就相當於"/",就是所有網址
路由get、post這些東西,也是中間件,中間件講究順序,匹配上第一個之后,就不會往后匹配了,next函數才能夠繼續往后匹配。如下實例:
all方法和HTTP動詞方法
針對不同的請求,Express提供了use方法的一些別名。比如,上面代碼也可以用別名的形式來寫。
上面代碼的all方法表示,所有請求都必須通過該中間件,參數中的“*”表示對所有路徑有效。get方法則是只有GET動詞的HTTP請求通過該中間件,它的第一個參數是請求的路徑。由於get方法的回調函數沒有調用next方法,所以只要有一個中間件被調用了,后面的中間件就不會再被調用了。
除了get方法以外,Express還提供post、put、delete方法,即HTTP動詞都是Express的方法。
這些方法的第一個參數,都是請求的路徑。除了絕對匹配以外,Express允許模式匹配。
上面代碼將匹配“/hello/alice”網址,網址中的alice將被捕獲,作為req.params.who屬性的值。需要注意的是,捕獲后需要對網址進行檢查,過濾不安全字符,上面的寫法只是為了演示,生產中不應這樣直接使用用戶提供的值。
如果在模式參數后面加上問號,表示該參數可選。
set方法
set方法用於指定變量的值。
上面代碼使用set方法,為系統變量“views”和“view engine”指定值。
response對象
| API | 含義 |
|---|---|
res.app |
同req.app |
res.append() |
追加指定HTTP頭 |
res.set() |
在res.append()后將重置之前設置的頭 |
res.cookie() |
設置Cookie |
res.clearCookie() |
清除Cookie |
res.download() |
傳送指定路徑的文件 |
res.get() |
返回指定的HTTP頭 |
res.json() |
傳送JSON響應 |
res.jsonp() |
傳送JSONP響應 |
res.location() |
只設置響應的Location HTTP頭,不設置狀態碼或者close response |
res.redirect() |
設置響應的Location HTTP頭,並且設置狀態碼302 |
res.send() |
傳送HTTP響應 |
res.sendFile() |
傳送指定路徑的文件 -會自動根據文件extension設定Content-Type |
res.set() |
設置HTTP頭,傳入object可以一次設置多個頭 |
res.status() |
設置HTTP狀態碼 |
res.type() |
設置Content-Type的MIME類型 |
(1)response.redirect方法
response.redirect方法允許網址的重定向。
response.redirect("/hello/anime");
response.redirect("http://www.example.com");
response.redirect(301, "http://www.example.com");
res.redirect()默認響應狀態碼是302
可以更改這個狀態碼作為res.redirect()的第一個參數
當在url地址欄中輸入http://localhost:3000
頁面就會重定向到http://localhost:3000/demo
(2)response.sendFile方法
response.sendFile方法用於發送文件。
response.sendFile("/path/to/anime.mp4");
(3)response.render方法
response.render方法用於渲染網頁模板。
app.get("/", function(request, response) {
response.render("index", { message: "Hello World" });
});
上面代碼使用render方法,將message變量傳入index模板,渲染成HTML網頁。
(4)res.send()
res.send用於向客戶端響應信息
並且它的強大之處在於可以智能的處理我們傳遞的不同類型參數
當參數為字符串,會將響應頭Content-Type默認設置為text/html
也就是解析為html呈現在我們的頁面上
當參數為數字,會自動幫我們設置響應體(狀態碼…)
當參數為數組或對象,它會響應一個JSON
requst對象
| API | 含義 |
|---|---|
req.app |
當callback為外部文件時,用於訪問express的實例 |
req.baseUrl |
獲取路由當前安裝的URL路徑 |
req.body/cookies |
獲得「請求主體」/ Cookies |
req.fresh/stale |
判斷請求是否還「新鮮」 |
req.hostname/ip |
獲取主機名和IP地址 |
req.originalUrl |
獲取原始請求URL |
req.params |
獲取路由的parameters |
req.path |
獲取請求路徑 |
req.protocol |
獲取協議類型 |
req.query |
獲取URL的查詢參數串 |
req.route |
獲取當前匹配的路由 |
req.subdomains |
獲取子域名 |
req.acceptsCharsets |
返回指定字符集的第一個可接受字符編碼 |
req.acceptsEncodings |
返回指定字符集的第一個可接受字符編碼 |
req.acceptsLanguages |
返回指定字符集的第一個可接受字符編碼 |
req.accepts() |
檢查可接受的請求的文檔類型 |
req.get() |
獲取指定的HTTP請求頭 |
req.is() |
判斷請求頭Content-Type的MIME類型 |
(1)request.ip
request.ip屬性用於獲得HTTP請求的IP地址。
(2)request.files
request.files用於獲取上傳的文件。
(3)req.query
req.query可以獲取請求路徑參數的對象
向服務器發送請求 http://localhost:3000/?user=tester&pass[a]=123&pass[b]=456
(4)req.params
req.params可以解析復雜路由規則上的屬性
(req.param綜合了req.query和req.param的功能,但是被移除了不要使用)
向服務器發送請求 http://localhost:3000/123456
這樣不論我在根路徑后輸入的是什么都會被解析為req.params.id
靜態資源
靜態資源就是指我們在開發中用到的css、js、img等等
它們需要存放到一個靜態資源目錄
當瀏覽器發出了一個非HTML文件請求
服務器就會從這個靜態資源目錄下去查找文件
我們一般在根目錄下創建一個public文件來存儲
並在public中創建stylesheets、javascripts、images等文件夾
用來存儲特定類型的資源
指定靜態資源目錄的方法上面已經提到了
比如說我們的html中有這樣的代碼
那么客戶端運行發出請求
服務器就會在public的javascripts文件夾下找到jquery.js靜態資源
模板引擎
express框架默認是ejs和jade渲染模板
路由
路由的意思就是根據不同的路徑,來指定不同的處理方法
我們一般把不同的路由封裝進不同的模塊
首先在根目錄下創建一個文件夾routes存儲路由
現在我在routes文件夾下創建倆個路由文件index.js和users.js
修改app.js
這樣表示http://localhost:3000/的路由交給index處理
http://localhost:3000/users的路由交給users處理
下面簡單的實現一下路由
通過express.Router()創建的router就像一個mini版的app一樣
app能做的,router都能做
只是我們把邏輯都封裝到了各個路由模塊中
上面代碼的結果:
body-parser中間件
其實express在3.x版本中內置了很多中間件
但是4.x版本就將出static以外的所有中間件全部抽離出來了
所以就需要我們單獨安裝
對照表如下:
| Express 3.0 | Express 4.0 |
|---|---|
| bodyParser | body-parser |
| compress | compression |
| cookieSession | cookie-session |
| logger | morgan |
| cookieParser | cookie-parser |
| session | express-session |
| favicon | static-favicon |
| response-time | response-time |
| error-handler | errorhandler |
| method-override | method-override |
| timeout | connect-timeout |
| vhost | vhost |
| csrf | csurf |
剛才就提到了POST請求有所不同
不同的地方就在於我們需要body-parser這個中間件來處理數據
通過req.body來獲得數據
首先使用前不要忘記下載
下面這四個方法分別用於對body內容采取不同的處理方法
bodyParser.json(options) 處理JSON數據
bodyParser.raw(options) 處理buffer數據
bodyParser.text(options) 處理文本數據
bodyParser.urlencoded(options) 處理UTF-8編碼數據
這樣我首先通過get請求獲取主頁面
提交表單向服務器發送post請求
服務器響應結果
express-generator:使用express搭建應用結構
express模塊有一個命令行工具express,可以用來生成基於express模塊的應用結構(網站結構)。
express 4.x之后,express命令被獨立出來放在了express-generator模塊中。我們用下面的命令全局安裝express這個命令行工具:
安裝完成后,在命令行環境下執行“express --version”,可以看到express的版本是4.16.1。
好了,現在我們使用express命令來創建一個默認的網站。
在命令行環境下導航到node.js這個目錄下,執行下面的命令:
然后可以看到:
仔細看上面的圖哦,它告訴了我們三類非常重要的信息:
express命令創建的網站的目錄結構以及創建的文件
安裝依賴(進入到HelloExpress下,執行npm install)
使用npm start啟動網站(express 4.x后)
按照響應的提示依次執行:
很快就可以看到下面的圖:
看到上圖,說明網站已正常運行。你可以在瀏覽器里訪問http://localhost:3000,然后就可以看到這個頁面:
到這里,express框架就搭建成功!
最后附上API中文地址:https://cloud.tencent.com/developer/section/1489347









