Express 總結

Express
Express提供了一個輕量級模塊,把nodejs的http功能封裝在一個簡單易用的接口中。Express也擴展了http模塊的功能,能輕鬆處理服務器的路由、響應、cookie和HTTP請求的狀態。
 
一 安裝和配置
1.全局安裝
npm install -g express   
輸入express -h若是出現:

執行:npm install -g express-generatorjavascript

咱們能夠查看express的版本,經過npm ls查看express和它的依賴的樹形結構css

2.Express的配置
express對象提供了set(setting,value)、enable(setting)和disable(setting)方法來爲應用程序的設置來設定值。
如啓用信任代理:app.enable('trust proxy');
通常能設置的有:
env    定義環境模式字符串,如development,testing,production,默認值是process.env.NODE_ENV
trust_proxy     啓用/禁用反向代理的支持,默認爲false
jsonp callback name  定義JSONP請求的默認回調名稱。默認值是?callback=
json replacer   定義JSON replacer回調函數,默認爲null
json spaces  指定當格式化JSON響應時使用的空格數量,默認在開發中爲2,在生產爲0
case sensitive routing   啓用/禁用區分大小寫,如/home與/Home是不同的,默認爲disabled
strict routing   啓用/禁用嚴格的路由,如/home和/home/是不同的,默認爲disabled
view cache  啓用/禁用視圖模板編譯緩存,默認爲enabled
view engine    指定呈現模板時,若是從視圖中省略了文件擴展名,應該使用的默認模板引擎擴展
views       指定模板引擎用來查找視圖模板的路徑,默認值是./views
 
二 啓動express服務器
var express=require('express');
var app=express();
app.listen(8080);
注意,listen()方法調用底層的HTTP鏈接綁定到port上,並開始監聽它。事實上,express()返回的值其實是一個回調函數,它映射了傳遞到http.createServer()和https.createServer()方法的回調函數。
用express實現HTTP和HTTPS服務器
var express=require('express');
var https=require('https');
var http=require('http');
var fs=require('fs');
var options={
    host:'127.0.0.1',
    key:fs.readFileSync('ssl/server.key'),
    cert:fs.readFileSync('ssl/server.crt')
};
http.createServer(app).listen(80);
https.createServer(options,app).listen(443);
app.get('/',function(req,res){
    res.send('Hello, Express');
});
一個典型的使用express的app.js,主要作了如下幾件事:
(1)導入相關模塊
(2)執行過var app=express()後,
使用app.set設置express內部的一些參數(options)
使用app.use來註冊函數
經過http.createServer用app來處理請求
實 際上,express經過app.use註冊middleware,middleware至關於request的handlers,在處理request 時,順序執行每個handler(function),handler業務完成後,經過調用next(),決定是否調用下一個handler,也就是所謂的鏈式處理。

 

三 路由 
1.能夠把路由定義爲兩部分,第一部分是HTTP請求方法,一般是get或post。第二部分是URL中指定的路徑。
app.get(path,[middleware],callback)
app.post(path,[middleware],callback)
其中,middleware是回調函數執行前要應用的中間件函數,callback是應該處理該請求並把響應發回給客戶端的請求處理程序,callback以Request對象做爲第一個參數,以Response對象做爲第二個參數。
此外,Express還提供了app.all()方法,該方法與post、get同樣,惟一的區別是,app.all()用於指定路徑的每一個請求,不論是任何一種方法。同時app.all()還能夠接受*做爲路徑的通配符,這對於實現記錄請求日誌和其餘特殊的功能來處理請求是一個很棒的特性,如:
app.all('*',function(req,res){
    //所有路徑的全局處理程序
});
2.在路由中應用參數
在複雜系統中,路由數量會不少,爲了減小路由數量,能夠在URL中實現參數。經過路由,能夠爲不一樣的請求提供惟一值來定義應用程序如何處理請求並生成響應。
實現路由參數主要有4種方法:
(1)查詢字符串,如?key=value&key=value...
var express=require('express');
var url=require('url');
var app=express();
app.get('/find',function(req,res){
    var url_parts=url.parse(req.url,true);
    var query=url_parts.query;
    res.send('Finding Book:Author: '+query.author+' Title: '+query.title);
});
若是是下面的URL:/find?author=Brad&title=Node
那麼res.send()方法返回的就是:Finding Book:Author:Brad Title: Node
(2)正則表達式
app.get(/^\/book\/(\w+)\:(\w+)?$/,function(req,res){
    res.send('Get Book: Chapter: '+req.params[0]+' page: '+req.params[1]);
});
若是是下面的URL:/book/12:15
res.send()方法返回:
Get Book: Chapter: 12 page: 15
注意:這裏的參數的值未被命名,req.params是與URL路徑中的條目匹配的數組。
(3)使用已定義的參數來應用路由參數
app.get('/user/:userid',function(req,res){
    res.send('Get User: '+req.param('userid'));
});
若是是下面的URL:/user/111
res.send()方法返回: Get User: 111
(4)爲已定義的參數應用回調函數
app.param(param,function(req,res,next,value){})
注意,這裏的next是一個用於已註冊的下一個app.param()回調的回調函數,必需要在回調函數中的某處調用next(),不然回調鏈會被破壞。value是從URL路徑解析的參數的值。
3.Request對象
Request對象是做爲第一個參數傳遞到路由處理程序,它的一些經常使用屬性和方法:
originalUrl      請求的原始URL字符串
protocol     協議的字符串,如http或https
ip   請求的ip地址
path    請求的路徑部分
host   請求的主機名
method    HTTP方法
query     請求的URL的查詢字符串部分
fresh    一個布爾值,當最後修改與當前匹配時爲true
stale   一個布爾值,當最後修改與當前匹配時爲false
secure   一個布爾值,當創建TLS鏈接時爲true
acceptsCharset(charset)   一個方法,若是由charset指定的字符集受支持,返回true
get(header)      返回header的值的方法
headers     請求標頭的對象形式
4.Response對象
傳遞到路由處理程序的Response對象提供了必要的功能來創建和發送適當的HTTP響應。
(1)設置標頭
get(header)    返回指定的header參數的值
set(header,value)    設置header參數的值
set(headerObj)    接受一個對象,包括多個'header':'value'屬性
locatio(path)    把location標頭設置爲指定的path參數
type(type_string)    根據type_string參數設置Content-Type標頭
attachment([filepath])    把Content-Disposition標頭設置爲attachment,而且若是指定filepath,則Content-Type頭是基於文件擴展名設置的
(2)設置狀態
res.status(200);   //正確
300    Rediction重定向
400     Bad Request錯誤的請求
401  Unauthorized未經許可
403   Forbidden禁止
500  Server Error服務器錯誤
(3)發送響應
res.send(status,[body])
body是一個String或者Buffer對象,若是指定Buffer對象,內容類型就被自動設置爲application/octet-stream(應用程序/八位字節流)
(4)發送JSON響應
res.json(status,[object])
如:
app.get('/json',function(req,res){
    app.set('json spaces',4);
    res.json({name:'bob',built:'1223',centers:['art','maths']});
});
app.get('jsonp',function(res,req){
    app.set('jsonp callback name','cb');
    res.jsonp({name:'bob',built:'1223',centers:['art','maths']});
});
注意,jsonp callback name被設置爲cb,意味着客戶端須要在URL中傳遞的不是?callback=<function>,而是?cb=<function>
(5)發送文件
res.sendFile(path,[options],[callback])
其中,path指向你要發送給客戶端的文件,options參數是一個對象,包含了一個maxAge屬性定義的最長期限和root屬性(用來支持path參數相對路徑的根路徑)。當文件傳輸完成時,回調函數被調用,並接受一個錯誤做爲惟一的參數。
如:
app.get('/image',function(req,res){
    res.sendFile('arch.jpg',{maxAge:1,   //24*60*60*1000
                                                root:'./views'},
            function(err){
                if(err){
                    console.log('Error');
                }else{
                    console.log('Success');
                }
            });
});
(6)發送下載響應:
res.download(path,[filename],[callback])
(7)重定向響應:
res.redirect(path);
如:
app.get('/google',function(req,res){
    res.redirect('http://google.com');
});
看路由的一些例子
(1)簡單的get請求
app.js
var express = require('express');
var app = express();
var index = require('./routes/index');
var users = require('./routes/users');
app.use('/', index);
app.use('/users', users);
index.js
var express = require('express');
var router = express.Router();
 
/* GET home page. */
router.get('/', function(req, res, next) {
  res.send('hello,index');
});
module.exports = router;
user.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});
module.exports = router;
項目結構如圖:

運行結果:html

 

(2)看一個正則匹配的例子
在index.js添加:
router.get('/ab*cd',function(req,res){
  console.log('/ab*cd GET請求');
  res.send('正則匹配');
});

(3)經過表單提交的post請求
新建index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<form method="post" action="http://localhost:3000/">
    <input type="submit" value="訪問" />
</form>
</body>
</html>

點擊訪問後出現:java

 

三 實現模板引擎
1.一個日益增加的趨勢是,使用模板文件和應用程序數據,藉助模板引擎來生成HTML,而不是從頭開始構建HTML文件。Express中兩個重要的模板,Jade和內嵌的javascript(EJS)。
Jade使用HTML的速記符號模板,模板文件很是小,可是須要掌握另外一種語言;EJS使用特殊的符號在正常的HTML文檔中嵌入javascript,使得它更容易從正常的HTML過分,可是該HTML會比原始文檔複雜的多,不如Jade模板簡潔。
2.安裝jade和ejs:
npm install jade --save
npm install ejs --save
安裝後能夠到package.json中查看
3.定義引擎模板
var app=express();
app.set('views','./views');     //也能夠寫成app.set('views',path.join(_dirname,'views'));即根目錄下的views文件夾下
app.set('view engine','jade');
看一個例子:
app.js:
var express = require('express');
var app = express();
var path = require('path');
//指明模板目錄:./views
app.set('views', path.join(__dirname, 'views'));
//使用ejs引擎
app.set('view engine', 'ejs');
node中的path.join方法:將多個參數組合成一個path
path.join([path1],[path2],...);
注意:該方法屬於path模塊,使用前須要引入path模塊
 
index.js
var express = require('express');
var router = express.Router();
//尋找views/index,提交ejs渲染,並返回結果
router.get('/', function(req, res, next) {
  res.render('index',{title:'express'});
});
module.exports = router;
 
使用ejs模板,index.ejs
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
  </body>
</html>

4.引入靜態文件
在app.js中添加:
app.use(express.static(path.join(__dirname, 'public')));
查看一下目錄文件,這裏咱們要引用的是public/stylesheets/style.css

index.ejs
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
  </body>
</html>
style.css:
body {
  padding: 50px;
  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
  color: #00B7FF;
}

 

四 Express中間件
1.Express提供的大部分功能是經過中間件函數完成的,這些中間件函數在nodejs收到請求的時點和發送響應的時點之間執行。Express的connect模塊提供了中間件框架,讓你方便的在全局或路徑級別或爲單個路由插入中間件功能。經過Express支持的中間件可讓你快速提供靜態文件,實現cookie,支持會話,處理post數據等等,你甚至能夠建立本身的自定義中間件函數,並利用它們來預處理請求和提供本身的功能。
2.有哪些中間件
Express創建在connect NPM模塊之上,提供了connect所提供的底層中間件支持。如下是Express支持的中間件:
static   容許Express服務器以流式處理靜態文件的GET請求,這個中間件是Express內置的,它能夠經過express.static()訪問
express-logger   實現一個格式化的請求記錄器來在跟蹤對服務器的請求
basic-auth-connect    提供對基本的HTTP身份驗證的支持
cookie-parser   能夠從請求讀取cookie並在響應中設置cookie
cookie-session   提供基於cookie的會話支持
express-session   提供了一個強大的會話支持
body-parser   把POST請求正文中的JSON數據解析爲req.body屬性
compression  對發給客戶端的大響應提供Gzip壓縮支持
caurf     提供跨站點請求僞造保護
3.安裝:
npm install body-parser --save
也能夠把express添加到package.json模塊,以確保當你部署應用程序時,這些模塊被安裝。
4.分配中間件
(1)在全局範圍內把中間件分配給某個路徑
要對全部路由指定中間件,能夠在Express app對象上實現Use()方法:
use([path],middleware)
其中,path是可選的,默認爲/,意味着全部的路徑,middleware是一個函數,即function(req,res,next){},每一箇中間件函數都有一個構造函數,它返回相應的中間件功能。next是要執行的下一個中間件函數。
例如,把body-parser中間件應用於全部路徑:
var express=require('express');
var bodyParser=require('body-parser');
var app=express();
app.use('/',bodyParser());
(2)把中間件分配到單個路由
var express=require('express');
var bodyParser=require('body-parser');
var app=express();
app.get('/parseRoute',bodyParser(),function(req,res){
        //function
});
(3)添加多箇中間件函數
能夠根據須要在全局範圍和路由上分配任意多的中間件函數。如:
var express=require('express');
var bodyParser=require('body-parser');
var cookieParser=require)('cookie-parser');
var session=require('express-session');
var app=express();
app.use('/',bodyParser()).use('/',cookieParser()).use('/',session());
注意,你分配函數的順序就是它們在請求中被應用的順序。一些中間件須要被添加在別的中間件函數前面。
相關文章
相關標籤/搜索