一、安裝
$ npm install express
代碼如下:
$ npm install -$ g express
二、快速上手
最快上手 express 的方法是利用可執行的 express(1) 來產生一個應用,如下所示:
程式碼如下:
$ express /tmp/foo && cd /tmp/foo
$ npm install -d
程式碼如下:
$ node app.js
三、建立一個伺服器
複製程式碼
程式碼如下:
app.get('/', function(req, res){ res.send('hello world');});
app.listen(3000);
程式碼如下:
var app = require('>
var app = require('>.createServer( { key: ... });
複製程式碼
程式碼如下:
app.configure(function(){ app.use(express.bodyParser());
app.use(app.router);
});
app.configure('development', function(){
app.use(express.static(__dirname '/public'));
});
複製程式碼
對於任何內部設定(#),Express 提供了 set(key[, val])、 enable(key) 和 disable(key) 方法:
譯註:設定詳見:application.js 的 app.set。
app.configure(function(>
app.configure(function(>
app.configure(function()){
.set('views', __dirname '/views');
app.set('views');
app.enable('some feature');
app.disable('some feature');
// 等價於:app.set('some feature', false);
app.enabled('some feature')
// => false複製代碼
$ NODE_ENV=production node app.js這很重要,因為多數緩存機制只在產品階段是被開啟的。
六、設定
Express 支援下列快速(out of the box)設定:
1.basepath 用於res.redirect() 的應用程式基本路徑(base path),明確處理綁定的應用程式(transparently handling mounted apps.)
2.view View 預設的根目錄為CWD/views
3.view engine 預設View 引擎處理(View 檔案)並不需要使用後綴
4.view cache 啟用View 快取(在產品階段啟用)
6.case sensitive routes 路由中區分大小寫7.strit routing 啟用後(路由中的)結尾/ 將不會被忽略(譯註:即app.get('/sofish ') 和app.get('/sofish/') 將是不一樣的)8.json callback 啟用res.send() / res.json() 明確的jsonp 支援(transparent jsonp support)
七、路由
程式碼如下:
app.get('/user/:id', function(req, res){
res.send('user ' req.params.id);複製程式碼
程式碼如下:
// 修改這個官方的字串
程式碼如下:
app.get(/^/users?(>
複製程式碼
程式碼如下:
$ curl:$ /dev:3000/user
[null,null]
[null,null]
$ curl http://dev:3000/users /1
"/user/:id"
/user/12
"/users/:id?"
/users/5
/users
"/files/*"
/files/jquery.js
/files/javascripts/jquery.js
"/file/*.*"
/files/jquery.js
/files/javascripts/jquery.js
"/user/:id/:operation?"
/user/1
/user/1/edit
"/products.:format"
/products.json
/products.xml
"/products.:format?"
/products.json
/products.xml
/products
"/user/:id.:format?"
/user/12
/user/12.json
舉個例子,我們可以使用POST 發送json 數據,透過bodyParser這個可以解析json 請求內容(或其他內容)的中間件來傳回數據,並將回傳結果存於req.body 中:
var express = require('express')
, app = express.createServer();
app.use(express.bodyParser());
app.post('/', function(req, res){
res.send(req.body);
});
app.listen(3000);
通常我們可以使用一個像 user/:id 這樣,沒有(命名)限制的「傻瓜」式的佔位符。然而比方說,我們要限制用戶id 只能是數字,那麼我們可能使用/user/:id([0-9] ),這個將僅當佔位符是包含至少一位數字時才生效(適配,match)。
八、進路控制(Passing Route Control)
我們可以透過呼叫第三個參數,next() 函數,來控制下一個適配的路由。如果找不到適配,控制權將會傳回給 Connect,同時中間件將會依 use() 中新增的順序依序呼叫。道理同樣適應多個定義到同一路徑的路由,他們將會依序被呼叫直到其中某個不呼叫 next() 而決定做出請求回應。
app.get('/users/:id?' , function(req, res, next){
var id = req.params.id;
if (id) {
ext();
}
});
app.get('/users', function(req, res){ // do something else
});
app.all() 方法只呼叫一次就可以方便地把同樣的邏輯到所有HTTP 動作。下面我們使用它來從偽數據中提取一個用戶,將其賦給 req.user。
var express = require('express')
var express = require('express') var users = [{ name: 'tj' }];
app.all('/user/:id/:op?', function(req, res, next){
req.user = users[req.params.id];
if (req .user) {
next();
} else {
next(new Error('cannot find user ' req.params.id));
}
app.get('/user/:id', function(req, res){
res.send('viewing ' req.user.name);
});
app.get('/user/:id/edit', function(req, res){
res.send('editing ' req.user.name);
});
app.put('/user/:id', function(req, res){
res.send('updating ' req.user.name);
});
app.get('*', function(req, res){
res.send(404, 'what???');
});
app.listen(3000);
九、中間件
使用的 Connect 中間件(屬性)通常伴隨著你的一個常規 Connect 伺服器,被傳到 express.createServer() 。如:
var express = require('
var express = require('express');
var app = express.createServer(
, express.bodyParser()
);
通常,使用connect 中間件你可能會用到require('connect'),像這樣:
var connect = require('connect');
app.use(connect.logger());
app.use(connect.bodyParser());
這在某種程度上來說有點不爽,所以express 重導出(re-exports)了這些中間件屬性,儘管他們是一樣的:
app.use(express.logger());
app.use(express.bodyParser());
中間件的順序非常重要,當Connect 收到一個請求,我們傳到createServer() 或use() 執行的第一個中間件將附帶三個參數,request、response,以及一個回調函數(通常是next)。當 next() 被調用,將輪到第二個中間件,依此類推。之所以說這是值得注意的,是因為許多中間件彼此依賴,例如methodOverride() 查詢req.body 方法來檢測HTTP 方法重載,另一方面bodyParser() 解析請求內容並將其於寄存於req. body。另一個例子是 cookie 解析和 session 支持,我們必須先 use() cookieParser() 緊接著 session()。
很多Express 應用程式都包含這樣的一行app.use(app.router),這看起來可能有點奇怪,其實它只是一個包含所有定義路由規則,並執行基於現有URL 請求和HTTP 方法路由查找的一個中間件功能。 Express 允許你決定其位置(to position),不過預設情況下它被放置於底部。透過改變路由的位置,我們可以改變中間件的優先級,譬如我們想把錯誤報告做為最後的中間件,以便任何傳給next() 的異常都可以透過它來處理;又或者我們希望靜態文件服務優先順序更低,以允許我們的路由可以監聽單一靜態檔案請求的下載次數,等等。這看起來差不多是這樣的:
app.use( express.logger(...));
app.use(express.bodyParser(...));
app.use(express.cookieParser(...));
app.use (express.session(...));
app.use(app.router);
app.use(express.static(...));
app.use(express.errorHandler (...));
首先我們加入logger(),它可能包含node 的req.end() 方法,提供我們回應時間的資料。接下來請求的內容將會被解析(如果有資料的話),緊接著的是cookie 解析和session 支持,同時req.session 將會在觸發app.router 中的路由時被定義,這時我們並不調用next(),因此static() 中間件將不會知道這個請求,如若已經定義瞭如下一個路由,我們則可以記錄各種狀態、拒絕下載和消耗下載點數等。
var downloads = {};
var downloads = {};
;
;
;
;
;
;
;;;
;;
;;
;
十、路由中間件
通常非同步資料擷取看起來可能像下例,我們使用:id 參數,嘗試載入一個使用者: 程式碼如下:app.get('/user/:id', function(req, res, next){ loadUser(req.params.id, function(err, user ){ if (err) return next(err); res.send('Viewing user ' user.name); });}); });});為保證DRY 原則和提升可讀,我們可以把這個邏輯應用在一個中間件內。如下所示,抽象這個邏輯到中間件內將允許你重複使用它,同時確保了我們路由的簡潔。 複製程式碼 程式碼如下:
function loadUser(req, res, next) {
// You would fetch your user from the db
var user = users[req.params.id];
var user = users[req.params.id];
if (user = users[req.params.id];
if (user = users[user ) {
req.user = user;
next();
} else {
next(new Error('Failed to load user ' req.params.) ' }
app.get('/user/:id', loadUser, function(req, res){
res.send('Viewing user ' req.user.name);
多重路由可以,並依序應用到更深一層的邏輯,如限制一個用戶帳號的存取。下面的範例只允許經過鑑定的使用者才可以編輯他(她)的帳號。 程式碼如下:
function andRestrictToSelf(req, s,ext) > req.authenticatedUser.id == req.user.id
? next()
: next(new Error('Unauthorized'));
}
app.get('/user/:id/edit', loadUser, andRestrictToSelf, function(req, res){
res.send('Editing user ' req.user.name);
} );
時時刻刻銘記路由只是簡單的函數,如下所示,我們可以定義傳回中間件的函數以創建一個更具表現力,更靈活的方案。
function andRestrictTo(role) { req, res, next) {
req.authenticatedUser.role == role
? next()
>
app.del('/user/:id', loadUser, andRestrictTo('admin'), function(req, res){
res.send('Deleted user ' req.user.name);
});
常用的中間件「堆疊」可以透過一個陣列來傳遞(會被遞歸應用),這些中間件可以混著、匹配到任何層次(which can be mixed and matched to any degree)。
複製程式碼
app.get('/foo', a, function(){});
app.get('/bar', a, function(){});
app.get('/', a, middleware3, middleware4, function(){});
app.get('/', a, b, function(){});
對於這個實例的完整程式碼,請看route middleware example 這個倉庫。
十一、HTTP 方法
至此已接觸了好幾次 app.get(),除此這外 Express 還提供了其他常見的 HTTP 動作,如 app.post() 、app.del() 等等。
POST 用法的一個常用例子是提交一個表單。下面我們簡單地在 html 中把表單的 method 屬性設為 post,控制權將會指派給它下面所定義的路由。預設上Express 並不知道如何處理這個要求的內容,因此我們必須新增bodyParser 中介軟體,它將解析application/x-www -form-urlencoded 和application/json 請求的內容,並將變數存放在req.body 中。我們可以像下述示例一樣來使用這個中間件:
如下,我們的路由將有權存取 req.body.user 對象,當有 name 和 email 被定義時它將包含這兩個屬性(譯註:如果表單發送的內容不為空的話)。
app.post('/'unction(req. res){
console.log(req.body.user);
res.redirect('back');
});
當想要在一個表單中使用像PUT這樣的方法,我們可以使用一個命名為_method 的hidden input,它可以用以修改HTTP 方法。為了做這個,我們首先需要 methodOverride 中間件,它必須出現於 bodyParser 後面,以便使用它的 req.body中包含的表單值。
app.use(express.bodyParser(>
app.use(express.bodyParser()); 🎜>app.use(express.methodOverride());
程式碼如下:
app.put('/', function(){
});
十二、錯誤處理
程式碼如下:
程式碼如下:function NotFound(msg){
this.name = 'NotFound';
Error.call(this, mments);
Error.captureStackTrace(this, arguments.callee); 🎜>
app.get('/404', function(req, res){
throw new NotFound;
app.get('/500', function(req, res){
程式碼如下:
app.error(function(, req, reqer, req next){
if (err instanceof NotFound) {
🎜>}) ;
app.error(function(err, req, res) {
res.render('500.jade', {
error: err
我們的 app 同樣可以利用 Connect 的 errorHandler 中間件來報告異常。譬如當我們希望在「開發」 環境輸出stderr 異常時,我們可以使用:
程式碼如下:
app.use(express.errorHandler(true , dumpExceptions: true }));
errorHandler 中間件還可以在Accept: application/json 存在的時候回傳json,這對於開發重度依賴客戶端Javascript 的應用非常有用。
程式碼如下:
app.get('/user/:userId', function(req, res, next){
if (err) return next(err);
res.send('user ' user.name);
複製程式碼
程式碼如下:
User.get(id, function(err, user){
if (err) return next(err);
一旦這樣做,上述所述將會大幅提昇路由的可讀性,並且允許我們輕鬆地在整個程序中共享邏輯:
複製代碼
代碼如下:
res.send('user ' req.user.name);
});
下面這個範例使用 Jade 來處理 index.html。因為我們並未使用 layout: false,index.jade 處理後的內容將會被傳入到 layout.jade 中一個名為 body 的本地變數。
複製程式碼
新的view engine 設定允許我們指定預設的模板引擎,例如當我們使用jade 時可以這樣設定:
res.render('index');
對應於:
複製程式碼
代碼如下:
程式碼如下:
res.render('another-page. ejs');
程式碼如下:
app.set('view options', {複製程式碼
複製程式碼
它們同樣可以是絕對路徑:
複製程式碼
程式碼如下:Express 的 view 系統內建了部件(partials) 和集合器(collections)的支持,相當於用一個 “迷你” 的 view 替換一個文檔碎片(document fragment)。範例,在一個view 中重複渲染來顯示評論,我們可以使用部件集:
在使用中,部件集無償地提供了一些 “神奇” 本地變量的支持:
1.firstInCollection true,當它是第一個物件的時候
2.indexInCollection 在集合器物件中的索引
3.lastInCollection true,當它是最後一個物件的時候
4 .collectionLength 集合器物件的長度
本地變數的傳遞(生成)具備較高的優先權,同時,傳到父級 view 的本地變數對於子級 view 同樣適應。例如當我們用 partial('blog/post', post) 來渲染一個部落格文章,它將會產生一個 post 本地變量,在呼叫這個函數的 view 中存在本地變數 user,它將同樣對 blog/post 有效。 (譯註:這裡 partial 比較像 php 中的 include 方法)。
注意: 請謹慎使用部件集合器,渲染一個長度為 100 的部件集合數組相當於我們需要處理 100 個 view。對於簡單的集合,最好重複內置,而非使用部件集合器以避免開銷過大。
十六、View 查找
View 尋找相對於父級view (路徑)執行,如我們有一個view 頁面叫作views/user/list.jade,並且在其內部寫有partial('edit') 則它會嘗試載入views/ user/edit.jade,同理partial('../messages') 將會載入views/messages.jade。
View 系統也支援範本索引,讓你可以使用一個與 view 同名的目錄。例如在一個路由中,res.render('users') 得到的非 views/users.jade 即 views/users/index.jade。 (譯註:先處理
當使用上述view 索引,我們在與view 同一個目錄下,使用partial('users') 中引用views/users/index.jade,與此同時view 系統會嘗試索引../users/index,而無須我們呼叫partial('users')。
十七、Template Engines
下列為 Express 最常用的模板引擎:
1.Haml:haml 實作
2.Jade:haml.js 繼位者
3.EJS:嵌入式JavaScript
4.CoffeeKup:基於CoffeeScript 的模板
5.jQuery Templates
十八、Session 支援
Session 支援可以透過使用 Connect 的 session 中間件來取得,為此通常我們同時需要在其前面加上 cookieParser 中介軟體,它將解析並儲存 cookie 資料於 req.cookies 中。
app.use(express.cookieParser()); 🎜>app.use(express.session({ secret: "keyboard cat" }));
app.use(express.cookieParser());
app.use(express.session( { secret: "keyboard cat", store: new RedisStore }));
app.use(express.bodyParser());
app .use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat", store: new RedisStore }));
app.post('/add-to-cart', function(req, res){
// 我們可能透過一個表單POST 出多個item
// (在些使用bodyParser()中間件)
var items = req.body.items;
req.session.items = items;
res.redirect('back');
});
// 當返回時,頁面GET /add-to-cart
// 我們可以檢查req. session.items && req.session.items.length
// 來印出提示
if (req.session.items && req.session.items.length) {
req.session.items.length) {
, 'You have %s items in your cart', req.session.items.length);
}
res.render('shopping-cart');
});
對於 req.session 對旬,它還有像 Session#touch()、Session#destroy()、 Session#regenerate() 等用以維護和操作 session 的方法。更多的詳情請看 Connect Session 的文件。
十九、升級指南
對於使用Express 1.x 的同學,如果你有很重要的程序需要升級到2.x 以獲得更好的支持,請看官方非常詳細的遷移指南:http:/ /expressjs.com/guide.html#migration-guide

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

禪工作室 13.0.1
強大的PHP整合開發環境

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!