標籤:
相關閱讀:
Express 4.X API 翻譯[一] -- Application篇
Express 4.X Api 翻譯[二] -- Request篇
Express 4.X Api 翻譯[三] --- Response篇
Express 4.X Api 翻譯[四] --- Router篇
本文是Express 4.x Api翻譯系列的第一篇。由於筆者最近在學習NodeJs,剛剛接觸了Node式的開發模式,被非同步IO的編程方式深深吸引,於是準備系統學習一下這項新技術。因為沒有任何NodeJs的基礎,也不知道從何學起,之前也研究過ByVoid的《NodeJs開發指南》也不知道算不算入門。想試著寫一下裡面的微博例子,但是發現自己安裝的Express是最新的4.X,網上對於Express的內容本來就很少,更別說是最新的開發文檔了,索性就開始先翻譯一下Express的Api,本篇是Express 4.x中文手冊的第一篇,以下內容來自原文網站 >>>Express官方網站
寫在前面
本文適用的Express版本為V4.0.0,一下內容不能保證同樣適用於之前的版本。由於筆者屬於剛剛接觸Express所以沒有研究過之前的版本與4.0.0版本的區別,之後在接下來的時間裡,筆者會翻譯更多關於Express的文章供大家學習。
express()
建立一個express應用
var express = require(‘express‘);var app = express(); app.get(‘/‘,function(req,res){ res.send(‘hello world‘);});app.listen(3000);
setting
以下的設定選項將為您展示如何改變Express的行為:
- env 運行時環境,預設為process.env.NODE_ENV(NODE_ENV環境變數)或者”development”;
- trust proxy 啟用反向 Proxy模式,預設為未啟用;
- jsonp callback name JSON回呼函數替換體,預設為空白;
- case sensitive routing 用於啟用路由大小寫敏感,預設為未啟用,”/Foo”和”/foo”是相同對待的;
- strict routing 啟用嚴格路由模式,預設”/foo”和”/foo/”是相同對待的;
- view cache 啟用模板引擎編譯緩衝,在生產模式預設是開啟的;
- view engine 預設狀態下預設的模板引擎
- views 模板目錄位址,預設為”process.cwd() + ‘/views’”
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.disable(‘trust proxy‘);app.disabled(‘trust proxy‘);//=>false
app.use([path],function)
使用給定的中介軟體function,選擇性參數path,預設為”/”.
var express = require(‘express‘);var app = express(); //simple 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的回調參數req中找不到path。這麼設計是為了讓中介軟體可以在不需要更改任何代碼就可以在任意首碼的路徑下執行.這裡有個具體的例子,使用”./public”來管理靜態檔案,使用”express.static()”中介軟體
//GET /javascript/jquery.js//GET /style.css//GET /favicon.icoapp.use(express.static(__dirname + ‘/public‘));
例如你想為所有的靜態檔案增加首碼”/static”,你可以使用“掛載”功能來支援者也操作。被掛載的中介軟體函數是不會被調用的除非req.url中包含這個首碼,當函數被調用時,這個首碼是被剝去的。當然,這隻會影響這個函數,後面的中介軟體還是會看見req.url中的”/static”被包含的,除非這些中介軟體也被掛載在”/static”下。
//GET /static/javascripts/jquery.js//GET /static/style.css//GET /static/favicon.icoapp.use(‘/static‘,express.static(__dirname + ‘/public‘));
使用“被定義的”app.use()的順序非常重要,它們將被順序調用,因此app.use()調用的先後順序決定了中介軟體的優先順序。例如通常任何的日誌記錄中介軟體將被定義在任何被使用的中介軟體之前:
var logger = require(‘morgan‘); app.use(logger());app.use(express.static(__dirname + ‘/public‘));app.use(function(req,res){ res.send(‘Hello‘);});
現在假如你想忽略請求靜態檔案的記錄,但是又想繼續記錄logger()被定義之後的路由和中介軟體,那麼你只需要將static()移動到logger()之前就可以了。
app.use(express.static(__dirname + ‘/public‘));app.use(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‘));
app.engine(ext,callback)
註冊模板引擎的callback來處理副檔名為ext的檔案,預設情況下會根據檔案的副檔名開引入相應的模板引擎。例如,如果你試圖渲染一個”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‘)); } });});
或者說你只是傳遞一個回呼函數,在這種情況下,你將會有機會去改變app.param()的API,例如express-params定義了下面的回調情況,允許你通過Regex來限制給定的參數。
這個例子有點進階,當檢測到如果第二個參數為Regex的話,返回一個很像上面”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.param(‘id‘,/^\d+$/);app.get(‘/user/:id‘,function(req,res){ res.send(‘user‘ + req.params.id);}); app.apram(‘range‘,/^(\w+)\.\.(\W+)?$/); app.get(‘/range/:range‘,function(req,res){ var range = req.param.range; res.send(‘from ‘ + range[1] + ‘to ‘ + range[2] );});
app.VERB(path,[callback...],callback)
app.VERB()方法為Express提供了路由方法,這裡的VERB指的是一種HTTP動作,比如說app.post()。可以提供多個callback,這多個callback都將會被同等對待,他們的行為就像是中介軟體一樣,但也有一個例外的情況,如果某一個callback調用了next(‘route’),那麼他後面的callback就會被忽略。這種情況會被應用在當滿足一個路由首碼,但是不需要用這個回呼函數處理這個路由,於是就把它向後傳遞。
下面的這個程式碼片段示範了一個最簡單的路由定義。Express會吧字串運算式轉換為Regex,然後在內部匹配傳入的運算式。請求參數將不會被考慮進來。例如 “GET /”將會匹配下面的路由規則,同樣 “GET /?name=tobi”也會被下面的規則匹配。
app.get(‘/‘,function(req,res){ res.send(‘Hello World‘);});
Regex也是可以被使用的,尤其是在你有特別的限制時這將會是非常有用的,例如下面的例子將會匹配 “GET /commits/71dbb9c” 同樣也會匹配 “GET /commits/71dbb9c..4c084f9″。
app.get(/^\/commits\/(\w+)(?:\..\..(\w+))?$/,function(req,res){ var from = req.params[0]; var to = req.params[1] || ‘HEAD‘; res.send(‘commit range ‘ + from + ‘...‘ + to);});
可以傳遞一些回調,這對於複用一些載入資源、校正中介軟體很有作用
app.get(‘/user/:id‘,user.load,function(){ //......});
如果你有眾多的中介軟體為一個路由規則,你也可以使用路由ap的all()。
var middleware = [loadForum,loadThread]; app.route(‘/forum/:fid/thread/:tid‘) .all(loadForum) .all(loadThread) .get(function(){ //.....}) .post(function(){//......})
所有的中介軟體規則將會被應用與GET 和 POST 請求。
app.all(path,[callback...],callback)這個方法函數就像是app.VERB()方法,但是不同的是他匹配所有的HTTP動作。這個方法在將”全域”映射為特定路徑的邏輯映射或者是任意映射是非常有用的。例如,如果你要把下面的路由定義放置在其他所有路由定義之前,這將導致從這個規則起所有的請求都將需要身分識別驗證,並自動載入一個使用者。請記住,所有的回呼函數都不應該被當做終點,loadUser可以被當做是一個任務,然後去調用next()來繼續匹配隨後的路由規則。
app.all(‘*‘,requireAuthentication,loadUser);
它相當於:
app.all(‘*‘,requireAuthentication);app.all(‘*‘,loadUser);
另一個更好的例子就是全域白名單函數,這個例子很像之前的,然而它限制了首碼必須為”/api”:
app.all(‘/api/*‘,requireAuthentication);
app.route(path)
返回一個路由的執行個體然後可以用於處理HTTP動作使用可選擇的中介軟體。使用app.route()是一個推薦的方法來避免重複命名路由規則以及由此帶來的錯誤。
var app = express(); app.route(‘/events‘) .all(function(req,res,next){ //runs for all HTTP verbs first //think of it as route specific middleware! }) .get(function(req,res,next){ res.json(......); }) .post(function(req,res,next){ //maybe add a new event....});
app.locals
應用程式的本地變數會被附加給所有在這個應用程式內渲染的模板。這是一個非常有用的模板函數,就像是應用程式級的資料一樣。
app.locals.title = "My App";app.locals.strftime = require(‘strftime‘);app.locals.emall = ‘[email protected]‘;
app.locals對象是一個Javascript對象。添加到它的屬性,將會被當做局部變數在應用程式中被公開。
app.locals.title//=>‘My App‘app.locals.email// =>‘[email protected]‘
預設情況下Express之有一個應用程式級的局部變數,那就是setting。
app.set(‘title‘,‘My App‘);//use settings.title in a view
app.render(view,[options],callback)
渲染 view,callback用來處理返回渲染後的字串。這個是res.render()的應用程式級的版本,它們的行為是一樣的。
app.render(‘email‘,function(err,html){ //.......});app.render(‘email‘,{name:‘Tobi‘},function(err,html){ //.......})
app.listen()
在給定的主機和連接埠上監聽請求,這個和node的文檔http.Server#listen()是一致的
var express = require(‘express‘);var app = express();app.listen(3000);
通過express()返回的 app 事實上是一個Javascript函數,它被設計為傳遞給node的http Server作為處理請求的回呼函數。由於app並不是通過HTTP或HTTPS繼承來的,它只是一個簡單的callback,所以這允許你很輕鬆的使用同樣的代來處理HTTP和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);}
轉自:http://www.90it.net/expressjs-4-api-zh-cn-application.html
Nodejs Express 4.X 中文API 1--- Application篇